import { readFileSync } from 'node:fs';
import { Agent as HttpsAgent } from 'node:https';
import { Client } from 'minio';

const endpoint = process.env.MINIO_ENDPOINT ?? 'localhost';
const port = Number(process.env.MINIO_PORT ?? 9000);
const useSSL = (process.env.MINIO_USE_SSL ?? 'false').toLowerCase() === 'true';
const accessKey = process.env.MINIO_ACCESS_KEY;
const secretKey = process.env.MINIO_SECRET_KEY;
const insecureSkipTlsVerify = (process.env.MINIO_INSECURE_SKIP_TLS_VERIFY ?? 'false').toLowerCase() === 'true';
const tlsRejectUnauthorized = (process.env.MINIO_TLS_REJECT_UNAUTHORIZED ?? 'true').toLowerCase() !== 'false';
const minioCaCertPath = process.env.MINIO_CA_CERT_PATH?.trim();

if (!accessKey || !secretKey) {
  throw new Error('MINIO_ACCESS_KEY and MINIO_SECRET_KEY must be set');
}

export const minioBucket = process.env.MINIO_BUCKET ?? 'videos';
export const minioPresignedExpirySeconds = Number(process.env.MINIO_PRESIGNED_EXPIRY_SECONDS ?? 60 * 10);
const customCa = minioCaCertPath ? readFileSync(minioCaCertPath) : undefined;
const transportAgent = useSSL
  ? new HttpsAgent({
      keepAlive: true,
      ca: customCa,
      rejectUnauthorized: insecureSkipTlsVerify ? false : tlsRejectUnauthorized,
    })
  : undefined;

export const minioClient = new Client({
  endPoint: endpoint,
  port,
  useSSL,
  accessKey,
  secretKey,
  transportAgent,
});

let ensureBucketPromise: Promise<void> | null = null;

export const ensureMinioBucket = async (): Promise<void> => {
  if (ensureBucketPromise) {
    return ensureBucketPromise;
  }

  ensureBucketPromise = (async () => {
    const exists = await minioClient.bucketExists(minioBucket);

    if (!exists) {
      await minioClient.makeBucket(minioBucket, process.env.MINIO_REGION ?? 'us-east-1');
    }
  })();

  try {
    await ensureBucketPromise;
    console.log("Minio Up")
  } catch (error) {
    ensureBucketPromise = null;
    throw error;
  }
};
