#!/usr/bin/env node

import { Command } from "commander";
// NOTE: this changed in node 18 to be node:url for...stupid
import { fileURLToPath } from "url";
import { glob } from "./lib/builderator.js";
import path from "path";
import assert from "assert";
import fs from "fs";

// BUG: this will load the commands but most of them assume the root
const __filename = fileURLToPath(import.meta.url);
const { dir } = path.parse(__filename);
let __dirname = dir;

// now even exec commands will know where the project root is
process.env['PROJECT_ROOT'] = __dirname;
const program = new Command();
// remember that glob doesn't like windows \
const command_dir = `${__dirname}/commands`;

if(!fs.existsSync(command_dir)) {
  console.error("ERROR: there is no command directory at", command_dir);
  process.exit(1);
}

program
  .name("bando")
  .description("Command runner for the bando project.")
  .version("0.1.0");

// only load the commands modules if any options are given

if(process.argv.length === 2) {
  console.log("COMMANDS:\n");
  const commands = glob(`${command_dir}/*.js`).map(cmd => {
    console.log(path.parse(cmd).name);
  });


  if(process.platform === "win32") {
    console.log("\nUse './bando help' for full help.");
  } else {
    console.log("\nUse './bando.js help' for full help.");
  }

} else {
  for(let command of glob(`${command_dir}/*.js`)) {
    try {
      const { name } = path.parse(command);
      const mod = await import(command);

      assert(mod.description, `export const description missing in ${command}`);
      assert(mod.main, `export const main missing in ${command}`);

      const build = program.command(name)
        .description(mod.description)
        .action(mod.main);

      if(mod.options) {
        mod.options.forEach(opt => build.option(...opt));
      }

      if(mod.required) {
        mod.required.forEach(opt => build.requiredOption(...opt));
      }

      if(mod.argument) {
        build.argument(...mod.argument);
      }
    } catch(error) {
      console.log(error, `Loading file ${command}`);
    }
  }
}

try {
  program.parse();
} catch(error) {
  console.log("------------- ERROR, here's the stack trace.");
  console.error(error.stack);
  process.exit(1);
}
