import { GetObjectCommand, HeadObjectCommand, NotFound, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
import { Readable } from 'stream';

const s3 = new S3Client({ region: 'us-east-1' });

export const getObjectReadableStream = (bucket: string, key: string): Promise<Readable> => {
  return new Promise(async (resolve, reject) => {
    const getObjectCommand = new GetObjectCommand({ Bucket: bucket, Key: key });

    try {
      const response = await s3.send(getObjectCommand);
      const readable = response.Body as Readable;
      return resolve(readable);
    } catch (err) {
      return reject(err);
    }
  });
};

export const getObject = (bucket: string, key: string): Promise<Buffer> => {
  return getObjectReadableStream(bucket, key).then((readable) => {
    return new Promise((resolve, reject) => {
      try {
        let responseDataChunks = [];
        readable.once('error', (err) => reject(err));
        readable.on('data', (chunk) => responseDataChunks.push(chunk));
        readable.once('end', () => resolve(Buffer.concat(responseDataChunks)));
      } catch (err) {
        return reject(err);
      }
    });
  });
};

export const checkObjectExists = async (bucket: string, key: string): Promise<boolean> => {
  const headObjectCommand = new HeadObjectCommand({ Bucket: bucket, Key: key });
  try {
    await s3.send(headObjectCommand);
  } catch (err) {
    if (err instanceof NotFound) {
      return false;
    }
    throw err;
  }
  return true;
};

export const putObject = async (bucket: string, key: string, buffer: Buffer): Promise<void> => {
  const putObjectCommand = new PutObjectCommand({ Bucket: bucket, Key: key, Body: buffer });
  await s3.send(putObjectCommand);
};
