#!/usr/bin/env node
// This file requires a shebang above. If it is missing, this is an error.

import { styleText } from 'node:util';

import { program } from 'commander';
import semver from 'semver';

import packageJSON from '../package.json' with { type: 'json' };
import './util/terminate.js';

import { checkSystem, SystemCheckContext } from './util/check-system.js';

if (!semver.satisfies(process.versions.node, packageJSON.engines.node)) {
  console.error(
    styleText('red', '✖'),
    `You are running Node.js version ${styleText('red', process.versions.node)}, but Electron Forge requires Node.js ${styleText('red', packageJSON.engines.node)}. \n`,
  );
  process.exit(1);
}

// Listr2 might be unsupported in certain versions, so import it after the Node version check.
// eslint-disable-next-line import/order
import { Listr } from 'listr2';

program
  .version(packageJSON.version, '-V, --version', 'Output the current version.')
  .helpOption('-h, --help', 'Output usage information.')
  .command(
    'start',
    'Start the current Electron application in development mode.',
  )
  .command('package', 'Package the current Electron application.')
  .command(
    'make',
    'Generate distributables for the current Electron application.',
  )
  .command('release', 'Release the current Electron application.')
  // `publish` is a deprecated alias for `release`. It is hidden from the help
  // output and prints a deprecation warning when invoked (see
  // electron-forge-publish.ts).
  .command('publish', 'Publish the current Electron application.', {
    hidden: true,
  })
  .passThroughOptions(true)
  .hook('preSubcommand', async (_command, subcommand) => {
    if (!process.argv.includes('--help') && !process.argv.includes('-h')) {
      const runner = new Listr<SystemCheckContext>(
        [
          {
            title: 'Checking your system',
            task: async (ctx, task) => {
              ctx.command = subcommand.name();
              ctx.git = !process.argv.includes('--skip-git');
              return await checkSystem(task);
            },
          },
        ],
        {
          concurrent: false,
          exitOnError: true,
          fallbackRendererCondition:
            Boolean(process.env.DEBUG) || Boolean(process.env.CI),
        },
      );

      try {
        await runner.run();
      } catch {
        process.exit(1);
      }
    }
  });

program.parse(process.argv);
