import { Client } from "minio";
import sharp from "sharp"
import {config} from "dotenv"
config()

// Retrieve MinIO details from environment variables
const minioEndpoint = process.env["S3_ENDPOINT_URL"] || "your-minio-endpoint";
const minioAccessKey = process.env["S3_ACCESS_KEY"] || "your-access-key";
const minioSecretKey = process.env["S3_SECRET_ACCESS_KEY"] || "your-secret-key";
const minioBucketName = "silvester23";

const minioClient = new Client({
  endPoint: minioEndpoint,
  accessKey: minioAccessKey,
  secretKey: minioSecretKey,
});


const objects = [];

const objectStream = minioClient.listObjects(minioBucketName);

for await (const obj of objectStream) {
  objects.push(obj);
}

async function compressObject(pngBuffer, fileName, format) {

  const newFilePath = `${fileName.slice(0, -4)}.${format}`;

  let buffer;
  switch (format) {
    case "webp":
      buffer = await sharp(pngBuffer).webp({ quality: 80 }).toBuffer();
      break;
    case "jpg":
      buffer = await sharp(pngBuffer).jpeg({ quality: 80 }).toBuffer();
      break;
    case "avif":
      buffer = await sharp(pngBuffer).avif({ quality: 80 }).toBuffer();
      break;
    default:
      throw new Error(`Unknown format ${format}`);
  }

  // Upload the JPG buffer back to the same MinIO bucket
  await minioClient.putObject(minioBucketName, newFilePath, buffer, {
    'Content-Type': 'image/' + format,
  });

  console.log(`Uploaded ${newFilePath} to MinIO`);
}

async function fetchBuffer(objectName) {
  const chunks = [];

  return new Promise((res, rej) => {
    minioClient.getObject(minioBucketName,objectName, function (err, dataStream) {
      if (err) {
        return console.log(err)
      }
      dataStream.on('data', function (chunk) {
        chunks.push(chunk);
      })
      dataStream.on('end', function () {
        res(Buffer.concat(chunks))
      })
      dataStream.on('error', function (err) {
        console.log(err)
        rej(err)
      })
    })
  })
}

const pngs = objects.filter((o) => o.name.endsWith(".png"));
console.log(`Found ${pngs.length} PNGs`);

for  (const obj of pngs) {
  const pngFilePath = obj.name;
  const jpgFilePath = pngFilePath.slice(0, -4) + ".jpg";
  const avifFilePath = pngFilePath.slice(0, -4) + ".avif";
  const webpFilePath = pngFilePath.slice(0, -4) + ".webp";

  const hasJpg = objects.some((o) => o.name === jpgFilePath);
  const hasAvif = objects.some((o) => o.name === avifFilePath);
  const hasWebp = objects.some((o) => o.name === webpFilePath);

  if(hasAvif && hasJpg && hasWebp) {
    continue;
  }

  const pngBuffer = await fetchBuffer(pngFilePath);

  if(!hasJpg) {
    await compressObject(pngBuffer, pngFilePath, "jpg");
  }

  if(!hasAvif) {
    await compressObject(pngBuffer, pngFilePath, "avif");
  }
  if(!hasWebp) {
    await compressObject(pngBuffer, pngFilePath, "webp");
  }

}
