import { existsSync } from 'fs';
import { CliTerseError } from '@alwaysai/alwayscli';

import { ALWAYSAI_CLI_EXECUTABLE_NAME } from '../../constants';
import { AppJsonFile, TargetJsonFile } from '../../core/app';
import { ProjectJsonFile } from '../../core/project';
import { logger, stringifyError } from '../../util';
import { logConfigFileErrorMessages } from '../../util/log-config-error-messages';
import { APP_PY_FILE_NAME, DOCKERFILE } from '../../paths';

export async function appCheckComponent(
  args: {
    ignoreTargetJsonFile?: boolean;
    ignoreAppJsonFile?: boolean;
    ignoreProjectJsonFile?: boolean;
    ignoreAppPyFile?: boolean;
    ignoreDockerfile?: boolean;
  } = {}
) {
  const {
    ignoreTargetJsonFile,
    ignoreAppJsonFile,
    ignoreProjectJsonFile,
    ignoreAppPyFile,
    ignoreDockerfile
  } = args;

  const checkFile = async (fileName: any) => {
    const file = fileName();
    if (!file.exists()) {
      throw new CliTerseError(
        await logConfigFileErrorMessages(
          file,
          MissingFilePleaseRunAppConfigureMessage
        )
      );
    }
    try {
      file.read();
    } catch (error) {
      logger.error(stringifyError(error));
      throw new CliTerseError(
        await logConfigFileErrorMessages(
          file,
          InvalidFilePleaseRunAppConfigureMessage
        )
      );
    }
  };

  if (!ignoreAppJsonFile) {
    await checkFile(AppJsonFile);
  }
  if (!ignoreTargetJsonFile) {
    await checkFile(TargetJsonFile);
  }
  if (!ignoreProjectJsonFile) {
    await checkFile(ProjectJsonFile);
  }
  if (!ignoreAppPyFile) {
    if (!existsSync(APP_PY_FILE_NAME)) {
      const errorMessage =
        MissingFilePleaseRunAppConfigureMessage(APP_PY_FILE_NAME);
      logger.error(errorMessage);
      throw new CliTerseError(errorMessage);
    }
  }
  if (!ignoreDockerfile) {
    if (!existsSync(DOCKERFILE)) {
      throw new CliTerseError(
        MissingFilePleaseRunAppConfigureMessage(DOCKERFILE)
      );
    }
  }
}

export function MissingFilePleaseRunAppConfigureMessage(fileName: string) {
  return `Missing file "${fileName}". Please run \`${ALWAYSAI_CLI_EXECUTABLE_NAME} app configure\` to set up this directory as an alwaysAI application.`;
}

export function InvalidFilePleaseRunAppConfigureMessage(fileName: string) {
  return `The file "${fileName}" does not appear to be properly formatted. Please validate the file or run \`${ALWAYSAI_CLI_EXECUTABLE_NAME} app configure\` to set up this directory as an alwaysAI application.`;
}
