#!/usr/bin/env node
import * as io from '@actions/io';
import * as core from '@actions/core';
import { exec } from '@actions/exec';

import OutputListener from './lib/output-listener.js';
import pathToCLI from './lib/stackql-bin.js';

async function checkStackQL () {
  // Setting check to `true` will cause `which` to throw if stackql isn't found
  const check = true;
  return io.which(pathToCLI, check);
}

(async () => {
  // This will fail if StackQL isn't found, which is what we want
  await checkStackQL();

  // Create listeners to receive output (in memory) as well
  const stdout = new OutputListener();
  const stderr = new OutputListener();
  const listeners = {
    stdout: stdout.listener,
    stderr: stderr.listener
  };

  // Execute stackql and capture output
  const args = process.argv.slice(2);
  const options = {
    listeners,
    ignoreReturnCode: true
  };
  const exitCode = await exec(pathToCLI, args, options);
  core.debug(`StackQL exited with code ${exitCode}.`);
  core.debug(`stdout: ${stdout.contents}`);
  core.debug(`stderr: ${stderr.contents}`);
  core.debug(`exitcode: ${exitCode}`);

  // Set outputs, result, exitcode, and stderr
  core.setOutput('stdout', stdout.contents);
  core.setOutput('stderr', stderr.contents);

  if (exitCode === 0 || exitCode === 2) {
    // A exitCode of 0 is considered a success
    // An exitCode of 2 may be returned when the '-detailed-exitcode' option
    // is passed to plan. This denotes Success with non-empty
    // diff (changes present).
    return;
  }

  // If we reach this point, it means that the exitCode was neither 0 nor 2,
  // which denotes an error. We can still use stderr.contents to provide more information about the error.
  core.setFailed(`StackQL exited with error code ${exitCode}. Details: ${stderr.contents}.`);
})();
