/**
 * Copyright Super iPaaS Integration LLC, an IBM Company 2024
 */
import AdmZip from "adm-zip";
import path from "path";
import { BaseAsset } from "../../model/assets-model.js";
import { isValidAsset } from "../../helpers/apim/asset-helper.js";
import { isValidRestAPI } from "../../helpers/common/rest-api-validation-helper.js";
import {
  isDirectory,
  isDirOrFileExists,
  isYamlFile,
  readDirectoryContents,
  readFile,
  isJsonFile,
  isOtherFile,
  getFileNameFromPath,
} from "../../helpers/common/fs-helper.js";
import {
  readMultiYaml,
  convertToYAMLString,
} from "../../helpers/common/yaml-helper.js";
import { readJson } from "../../helpers/common/json-helper.js";
import {
  showWarning,
  showError,
  showInfo,
} from "../../helpers/common/message-helper.js";
import {
  ASSERT_ADDED,
  DIRECTORY_DOESNT_EXIST,
  SPEC_ADDED,
  YAML_SEPARATOR,
  UNKNOWN_ERROR
} from "../../constants/message-constants.js";
import { DebugManager } from "../../debug/debug-manager.js";

const checkAndAddValidFileToZip = (
  content: BaseAsset,
  excludeKinds: string[],
  zipFile: AdmZip,
  filePath: string,
  zipFolderPath: string
) => {
  if(content){
    const kind = content?.kind ? content?.kind?.toLowerCase() : "";
    const validRestApi = isValidRestAPI(content);
    const validAsset = isValidAsset(content);
    if (validRestApi || validAsset) {
      if (!excludeKinds.includes(kind)) {
        zipFile.addLocalFile(filePath, zipFolderPath);
        if (validRestApi) {
          showInfo(SPEC_ADDED + filePath);
        } else {
          showInfo(ASSERT_ADDED + filePath);
        }
      }
    }
  };
  }
  

const combineValidAssetInMultiYaml = (
  contents: BaseAsset[],
  excludeKinds: string[]
) => {
  let combinedYaml = "";
  if(!contents) return combinedYaml;
  contents.forEach((content) => {
    if(content){
      const kind = content.kind ? content.kind.toLowerCase() : "";
      const validRestApi = isValidRestAPI(content);
      const validAsset = isValidAsset(content);
      if (validRestApi || validAsset) {
        if (!excludeKinds.includes(kind)) {
          const yamlString = convertToYAMLString(content);
          combinedYaml += YAML_SEPARATOR + yamlString;
        }
      }
    }
  });
  return combinedYaml;
};

export const checkAndAddValidYamlFile = (
  filePath: string,
  zipFolderPath: string,
  zipFile: AdmZip,
  excludeKinds: string[]
) => {
  try {
    const fileContent = readFile(
      path.dirname(filePath),
      path.basename(filePath)
    );
    const yamlContents = readMultiYaml<BaseAsset>(filePath, fileContent);

    // Process muli YAML file
    if (yamlContents.length > 1) {
      const fileName = getFileNameFromPath(filePath);
      const combinedYaml = combineValidAssetInMultiYaml(
        yamlContents,
        excludeKinds
      );
      zipFile.addFile(
        `${zipFolderPath}/${fileName}`,
        Buffer.from(combinedYaml)
      );
      showInfo(ASSERT_ADDED + filePath);
    }
    // Process single YAML file
    else {
      checkAndAddValidFileToZip(
        yamlContents[0],
        excludeKinds,
        zipFile,
        filePath,
        zipFolderPath
      );
    }
  } catch (error) {
    const errorMessage = `${error instanceof Error ? error.message : UNKNOWN_ERROR}`
    throw new Error(errorMessage);
  }
};

export const checkAndAddValidJsonFile = (
  filePath: string,
  zipFolderPath: string,
  zipFile: AdmZip,
  excludeKinds: string[]
) => {
  try {
    const fileContent = readFile(
      path.dirname(filePath),
      path.basename(filePath)
    );
    const jsonContent = readJson<BaseAsset>(filePath, fileContent);

    checkAndAddValidFileToZip(
      jsonContent,
      excludeKinds,
      zipFile,
      filePath,
      zipFolderPath
    );
  } catch (error) {
    const errorMessage = `${error instanceof Error ? error.message : UNKNOWN_ERROR}`
    throw new Error(errorMessage);
  }
};

export const checkAndAddOtherFile = (
  filePath: string,
  zipFolderPath: string,
  zipFile: AdmZip,
) => {
    zipFile.addLocalFile(filePath, zipFolderPath);
    showInfo(ASSERT_ADDED + filePath);
}

const addValidAssetsToZip = (
  folderPath: string,
  zipFolderPath: string,
  zipFile: AdmZip,
  excludeKinds: string[]
) => {
  if (!isDirOrFileExists(folderPath)) {
    if (DebugManager.getInstance().isDebugEnabled()) {
      showWarning(`${DIRECTORY_DOESNT_EXIST} ${folderPath}`);
    }
    return;
  }

  const items = readDirectoryContents(folderPath);

  zipFile.addFile(`${zipFolderPath}/`, Buffer.from(""));

  items.forEach((item) => {
    const itemPath = path.join(folderPath, item);
    const zipItemPath = path.join(zipFolderPath, item);

    if (isDirectory(itemPath)) {
      addValidAssetsToZip(itemPath, zipItemPath, zipFile, excludeKinds);
    } else if (isYamlFile(itemPath)) {
      checkAndAddValidYamlFile(itemPath, zipFolderPath, zipFile, excludeKinds);
    } else if (isJsonFile(itemPath)) {
      checkAndAddValidJsonFile(itemPath, zipFolderPath, zipFile, excludeKinds);
    } else if(isOtherFile(itemPath)) {
      checkAndAddOtherFile(itemPath, zipFolderPath, zipFile);
    }
  });
};

export { addValidAssetsToZip };
