import { CliTerseError } from '@alwaysai/alwayscli';
import { ALWAYSAI_CLI_EXECUTABLE_NAME } from '../../constants';
import {
  writeStandaloneDockerfileComponent,
  buildDockerImageComponent
} from '../docker';
import { JsSpawner, promptForInput, copyFile } from '../../util';
import { appCheckComponent } from './app-check-component';
import { requirePaidPlan } from '../../core/project';
import { TargetJsonFile } from '../../core/app';
import { VENV, DOCKERFILE_STANDALONE } from '../../paths';

export async function appPackageComponent(props: {
  yes: boolean;
  dockerImageTag?: string;
}): Promise<string> {
  const { yes } = props;
  await appCheckComponent();
  await requirePaidPlan();
  const targetJsonFile = TargetJsonFile();
  const targetConfig = targetJsonFile.read();

  switch (targetConfig.targetProtocol) {
    case 'docker:':
    case 'ssh+docker:': {
      if (!(await targetJsonFile.readHostSpawner().exists(VENV))) {
        throw new CliTerseError(
          `Python virtualenv not found! Did you run ${ALWAYSAI_CLI_EXECUTABLE_NAME} app install?`
        );
      }
      await writeStandaloneDockerfileComponent();

      if (targetConfig.targetProtocol === 'ssh+docker:') {
        await copyFile(
          JsSpawner(),
          targetJsonFile.readHostSpawner(),
          DOCKERFILE_STANDALONE
        );
      }

      let dockerImageTag = props.dockerImageTag;
      if (!yes && !dockerImageTag) {
        const tagAnswer = await promptForInput({
          purpose: 'to set a Docker image tag',
          questions: [
            {
              type: 'text',
              name: 'tag',
              message:
                'Enter a tag for the application Docker image. Format: <dockerhub-user>/<img-name>:<version>'
            }
          ]
        });
        dockerImageTag = tagAnswer.tag;
      }

      const targetHostSpawner = targetJsonFile.readHostSpawner();
      const appDockerImageId = await buildDockerImageComponent({
        targetHostSpawner,
        targetHardware: targetConfig.targetHardware,
        dockerImageTag,
        dockerfilePath: DOCKERFILE_STANDALONE
      });

      return dockerImageTag ?? appDockerImageId;
    }

    case 'native:':
    default:
      throw new CliTerseError(
        `Package can only be used with docker. Please run \`${ALWAYSAI_CLI_EXECUTABLE_NAME} app configure\` and select a remote device`
      );
  }
}
