import { Spinner } from '../../util/spinner';
import { confirmPromptComponent } from '../general/confirm-prompt-component';
import { CliTerseError } from '@alwaysai/alwayscli';
import { runWithSpinner } from '../../util/run-with-spinner';
import {
  SshDockerTargetConfig,
  TargetJsonFile
} from '../../core/app/target-json-file';
import { VENV, APP_MODELS_DIRECTORY_NAME } from '../../paths';
import { Spawner, logger, stringifyError } from '../../util';
import { appCleanDocker } from '../../core/app';

export async function appCleanDockerComponent(props: {
  targetHostSpawner: Spawner;
}) {
  const { targetHostSpawner } = props;
  await runWithSpinner(
    async () => {
      await targetHostSpawner.rimraf(VENV);
      await targetHostSpawner.rimraf(APP_MODELS_DIRECTORY_NAME);
    },
    [],
    'Clean app directory'
  );
}

export async function appCleanSshDockerComponent(props: {
  yes: boolean;
  targetConfig: SshDockerTargetConfig;
  targetHostSpawner: Spawner;
}) {
  const { yes, targetConfig, targetHostSpawner } = props;
  if (!yes) {
    const { targetHostname, targetPath } = targetConfig;
    const cleanDir = await confirmPromptComponent({
      message: `Are you sure you want to delete the outdated target directory (${targetHostname}:${targetPath}) and reinstall the updated app`
    });
    if (!cleanDir) {
      throw new CliTerseError('Operation canceled by user');
    }
  }

  const spinner = Spinner('Delete target directory');
  try {
    await targetHostSpawner.sanatizedrimraf();
    spinner.succeed();
  } catch (exception) {
    logger.error(stringifyError(exception));
    spinner.fail();
    throw exception;
  }
}

export async function appCleanComponent(props: { yes: boolean }) {
  const { yes } = props;
  const targetJsonFile = TargetJsonFile();
  const targetConfig = targetJsonFile.read();
  const targetHostSpawner = targetJsonFile.readHostSpawner();

  switch (targetConfig.targetProtocol) {
    case 'native:':
    case 'docker:': {
      await runWithSpinner(
        appCleanDocker,
        [{ targetHostSpawner }],
        'Clean app directory'
      );
      break;
    }

    case 'ssh+docker:': {
      await appCleanSshDockerComponent({
        yes,
        targetConfig,
        targetHostSpawner
      });
      break;
    }

    default: {
      throw new CliTerseError('Unsupported protocol');
    }
  }
}
