/**
 * Copyright IBM Corp. 2024, 2025
 */
import { loadAll } from 'js-yaml';
import JSZip from 'jszip';
import { ModelFactory } from '../model-factories/model.factory.js';
import { LogWrapper } from '../service/log-wrapper.js';
import { uploadedFileModel } from '../model-factories/fileupload.factory.js';

const { loadAsync: loadAsyncZip } = JSZip;
export class ZipTestModelTransformer {
  constructor() {}

  private async loadZipFiles(buffer: Buffer): Promise<JSZip> {
    return loadAsyncZip(buffer);
  }

  private parseContent(content: string, fileName: string): any[] {
    if (fileName.endsWith('.json')) {
      return [JSON.parse(content)];
    }
    const result = loadAll(content);
    return result;
  }

  /**
   * Transforms a zip buffer into an array of Test objects.
   *
   * @param {Buffer} zipBuffer - The zip buffer containing YAML or JSON files.
   * @returns {Promise<ModelFactory>} - A promise that resolves to an array of Test objects.
   *
   */
  async transform(zipBuffer: Buffer): Promise<ModelFactory> {
    LogWrapper.logInfo('0003', 'Starting file processing.');
    const zipFiles = await this.loadZipFiles(zipBuffer);
    const model = new ModelFactory();
    for (const [fileName, file] of Object.entries(zipFiles.files)) {
      if (file.dir) continue;
      if (fileName.match(/\.(ya?ml|json)$/i)) {
        const content = await file.async('string');
        const parsedData = this.parseContent(content, fileName);
        model.create(parsedData);
        continue;
      } else {
        /**
         * The uploaded file is added to the model and transmitted using a FormData request.
         * no need to kind check
         */
        const content = await file.async('nodebuffer');
        uploadedFileModel.create({ key: fileName, fileName, value: content });
        continue;
      }
    }
    model.resolveRefs();
    LogWrapper.logInfo('0003', 'File processing completed.');
    return model;
  }
}
