import * as plugins from './plugins.js';
import * as paths from './paths.js';
import * as tsbuild from './tsbuild.exports.js';

export const runCli = async () => {
  const tsbuildCli = new plugins.smartcli.Smartcli();

  /**
   * the standard task compiles anything in ts/ directory to dist directory
   */
  tsbuildCli.standardCommand().subscribe(async (argvArg) => {
    tsbuild.compileGlobStringObject(
      {
        './ts/**/*.ts': './dist_ts',
      },
      {},
      process.cwd(),
      argvArg
    );
  });

  /**
   * the custom command compiles any customDir to dist_customDir
   */
  tsbuildCli.addCommand('custom').subscribe(async (argvArg) => {
    const listedDirectories = argvArg._;
    listedDirectories.shift(); // removes the first element that is "custom"
    const compilationCommandObject: { [key: string]: string } = {};
    for (const directory of listedDirectories) {
      compilationCommandObject[`./${directory}/**/*.ts`] = `./dist_${directory}`;
    }
    await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
  });

  /**
   * the custom command compiles any customDir to dist_customDir
   */
  tsbuildCli.addCommand('tsfolders').subscribe(async (argvArg) => {
    const tsFolders = await plugins.smartfile.fs.listFolders(paths.cwd, /^ts/);

    // Now tsFolders contains all other folders except 'ts_shared' and 'ts_interfaces'

    // We've established a base order. Now let's look at tspublish.json based ranking.
    const tsPublishInstance = new plugins.tspublish.TsPublish();
    const tsPublishModules = await tsPublishInstance.getModuleSubDirs(paths.cwd);
    // tsPublishModules is an object: { [folderName]: tspublishJsonData }

    // Create an array with folder names and their ranks
    const foldersWithOrder = [];

    for (const folder of tsFolders) {
      let rank = Infinity; // Default rank if not specified
      if (tsPublishModules[folder] && tsPublishModules[folder].order !== undefined) {
        rank = tsPublishModules[folder].order;
      }
      foldersWithOrder.push({ folder, rank });
    }

    // Sort the folders based on rank
    foldersWithOrder.sort((a, b) => a.rank - b.rank);

    // Construct the sorted list of folders
    const sortedTsFolders = []; 

    // Add the rest of the folders in sorted order
    for (const item of foldersWithOrder) {
      sortedTsFolders.push(item.folder);
    }

    // Let's make sure 'ts_shared' is always transpiled first
    const ensurePosition = (folderNameArg: string, ensuredPosition: number) => {
      if (tsFolders.indexOf(folderNameArg) > -1 && Object.keys(tsPublishModules).indexOf(folderNameArg) === -1) {
        sortedTsFolders.splice(tsFolders.indexOf(folderNameArg), 1);
        sortedTsFolders.splice(ensuredPosition, 0, folderNameArg);
      }
    }

    ensurePosition('ts_interfaces', 0);
    ensurePosition('ts_shared', 1);


    const compilationCommandObject: { [key: string]: string } = {};
    console.log(`compiling in this order:`);
    console.log(sortedTsFolders);
    for (const tsFolder of sortedTsFolders) {
      compilationCommandObject[`./${tsFolder}/**/*.ts`] = `./dist_${tsFolder}`;
    }
    await tsbuild.compileGlobStringObject(compilationCommandObject, {}, process.cwd(), argvArg);
  });

  tsbuildCli.startParse();
};