import { spawn } from 'child_process';
import signalExit = require('signal-exit');
import rKill = require('tree-kill');
import { CliTerseError } from '@alwaysai/alwayscli';
import { Cmd } from '../types';
import { ALWAYSAI_OS_PLATFORM } from '../../../environment';
import { logger } from '../../logger';

export async function runForeground(cmd: Cmd) {
  const optString = cmd.args ? cmd.args.join(' ') : '';
  logger.debug(`${cmd.exe} ${optString}`);
  const childProcess = spawn(cmd.exe, cmd.args ?? [], {
    cwd: cmd.cwd,
    stdio: 'inherit'
  });

  // Kill child when parent exits
  signalExit(() => {
    if (ALWAYSAI_OS_PLATFORM === 'darwin') {
      childProcess.kill('SIGINT');
      // ensures the main process gets killed by the correct signal - this will only activate with a ctrl + c
      // when it hits the siginit it will then activate the on exit signal and finish
      process.on('SIGINT', () => {
        if (childProcess.pid) {
          rKill(childProcess.pid, 'SIGINT', (error?: Error | undefined) => {
            if (error) {
              throw new CliTerseError(
                `Failed to kill child process {error.name} {error.message}`
              );
            }
          });
        }
      });
    } else {
      childProcess.kill();
    }
  });

  return await new Promise<number | void>((resolve, reject) => {
    childProcess.on('error', (err) => {
      reject(err);
    });

    childProcess.on('exit', (code) => {
      if (code) {
        resolve(code);
      } else {
        resolve();
      }
    });
  });
}
