import * as core from '@actions/core';
import { logger } from './utils/logger';
import * as Plugin from './plugin';
import {PluginInfo} from "./plugin/plugin";

async function exec() {
  const debug  = core.getInput('debug') || process.env['DEBUG'];
  if (debug) {
    logger.level = 'debug';
  }
  const plugin = core.getInput('run');
  if (plugin) {
    const args = core.getInput('params').split(' ').map(item => item.trim()).filter(item => item);
    return execPlugin(plugin, ...args);
  }
  if (process.argv.length < 3) {
    logger.error('unknown command');
    return;
  }
  const command = process.argv[2];
  const args = process.argv.slice(3);
  return handleCommand(command, args);
}

async function execPlugin(plugin: string, ...args: string[]) {
  try {
    await Plugin.exec(plugin, ...args);
    core.setOutput('code', 0);
  } catch (outputs) {
    logger.error(`exec plugin failed, err: ${outputs?.stderr || outputs}`);
    core.setOutput('code', outputs?.code || 1);
    const failedWhenNonZeroExit = core.getInput('failedWhenNonZeroExit');
    if (failedWhenNonZeroExit) {
      core.setFailed(outputs?.toString());
    }
  }
}

async function handleCommand(command: string, args: string[]) {
  switch (command) {
    case 'run':
      return run(args);
    case 'list':
      return list();
    case 'install':
      return install(args);
    case 'uninstall':
      return uninstall(args);
    default:
      logger.error(`unknown command: ${command}`);
      return;
  }
}

async function run(args: string[]) {
  if (!args || args.length == 0) {
    logger.error(`no target to run`);
    return;
  }
  const plugin = args[0];
  const params = args.slice(1);
  return execPlugin(plugin, ...params);
}

async function list() {
  const items = await Plugin.installedList(false);
  if (items.size === 0) {
    logger.info('no plugin was installed');
    return;
  }
  for (const [plugin, info] of items) {
    console.log(`[${info.getType()}] ${plugin}@${info.installVersion}${getAdditionVersion(info)}`);
  }
}

async function install(args: string[]) {
  if (args.length == 0) {
    logger.error(`no plugins need to be installed`);
    return;
  }
  const pi = await Plugin.install(args[0], true);
  logger.info(`the ${pi.name}@${pi.installVersion}${getAdditionVersion(pi)} has been installed at ${pi.path}`);
}

async function uninstall(args: string[]) {
  if (args.length == 0) {
    logger.error(`no plugins need to be uninstalled`);
    return;
  }
  const pi = await Plugin.uninstall(args[0]);
  logger.info(`[${pi.name}@${pi.installVersion}]${getAdditionVersion(pi)} has been uninstalled`);
}

function getAdditionVersion(pi: PluginInfo): string {
  return pi.installVersion === pi.realVersion ? "" : ` (${pi.realVersion || pi.installVersion})`;
}

exec().catch((e) => {
  logger.info(`exec plugin failed: ${e}`);
  process.exit(e?.status || 1);
});
