import * as boxen from 'boxen';
import * as chalk from 'chalk';
import { ALWAYSAI_OS_PLATFORM } from '../../environment';
import { getSystemId } from '../../infrastructure';
import {
  downloadJson,
  echo,
  getLatestVersionFromNpm,
  logger,
  stringifyError
} from '../../util';

import { version } from '../../version';

const appPrompt = 'Please open the alwaysAI Desktop app to update. ';
const npmPrompt = "Please run 'npm install -g alwaysai' to update. ";
const updatePrompt = `A new version of the CLI is available! \n\n`;

type CliManifest = {
  version: string;
  path: string;
  sha512: string;
  releaseDate: string;
  dependencies: {
    name: string;
    path: string;
    outputFilename: string;
  }[];
};

async function getManifest(manifestName: string) {
  let bucket: string;
  switch (getSystemId()) {
    case 'development': {
      bucket = 'alwaysai-artifacts-dev';
      break;
    }
    case 'qa': {
      bucket = 'alwaysai-artifacts-qa';
      break;
    }
    case 'production':
    case 'local':
    default:
      bucket = 'alwaysai-artifacts-prod';
  }
  const aaiCLIArtifactsURL = `https://${bucket}.s3.us-west-1.amazonaws.com/cli`;

  const manifest = (await downloadJson(
    `${aaiCLIArtifactsURL}/${manifestName}`
  )) as CliManifest;
  return manifest.version;
}

async function getLatestVersion(): Promise<string> {
  let latestVer = '';
  try {
    switch (ALWAYSAI_OS_PLATFORM) {
      case 'win32':
        latestVer = await getManifest('cli-win.json');
        break;
      case 'darwin':
        latestVer = await getManifest('cli-macos.json');
        break;
      case 'linux':
        latestVer = await getLatestVersionFromNpm('alwaysai');
        break;
      default:
        throw new Error(`Unsupported OS: ${ALWAYSAI_OS_PLATFORM}`);
    }
  } catch (error) {
    logger.error(stringifyError(error));
  }
  return latestVer;
}

function constructPrompt(props: { CLIversion: string; latestVer: string }) {
  const { CLIversion, latestVer } = props;
  let platformPrompt = appPrompt;
  if (ALWAYSAI_OS_PLATFORM === 'linux') {
    platformPrompt = npmPrompt;
  }
  const prompt = `${chalk.bold(
    updatePrompt
  )}${platformPrompt}\nYour version: ${CLIversion}. Newest version: ${latestVer}`;
  return prompt;
}

export async function checkForUpdatesAndPrompt() {
  try {
    const latestVersion = await getLatestVersion();
    const CLIversion = version;

    if (CLIversion !== latestVersion) {
      echo(
        `${chalk.yellow(
          boxen(
            constructPrompt({
              CLIversion,
              latestVer: latestVersion
            }),
            { borderStyle: 'round', textAlignment: 'center', padding: 1 }
          )
        )}`
      );
    }
  } catch (error) {
    logger.error(stringifyError(error));
  }
}
