'use strict';

const fs = require('fs');
const path = require('path');

// Create an object of all benchmark scripts
const benchmarks = {};
fs.readdirSync(__dirname)
  .filter((name) => {
    return name !== 'fixtures' &&
           fs.statSync(path.resolve(__dirname, name)).isDirectory();
  })
  .forEach((category) => {
    benchmarks[category] = fs.readdirSync(path.resolve(__dirname, category))
      .filter((filename) => filename[0] !== '.' && filename[0] !== '_');
  });

function CLI(usage, settings) {
  if (process.argv.length < 3) {
    this.abort(usage); // Abort will exit the process
  }

  this.usage = usage;
  this.optional = {};
  this.items = [];
  this.test = false;

  for (const argName of settings.arrayArgs) {
    this.optional[argName] = [];
  }

  let currentOptional = null;
  let mode = 'both'; // Possible states are: [both, option, item]

  for (const arg of process.argv.slice(2)) {
    if (arg === '--') {
      // Only items can follow --
      mode = 'item';
    } else if (mode === 'both' && arg[0] === '-') {
      // Optional arguments declaration

      if (arg[1] === '-') {
        currentOptional = arg.slice(2);
      } else {
        currentOptional = arg.slice(1);
      }

      if (settings.boolArgs && settings.boolArgs.includes(currentOptional)) {
        this.optional[currentOptional] = true;
        mode = 'both';
      } else {
        // Expect the next value to be option related (either -- or the value)
        mode = 'option';
      }
    } else if (mode === 'option') {
      // Optional arguments value

      if (settings.arrayArgs.includes(currentOptional)) {
        this.optional[currentOptional].push(arg);
      } else {
        this.optional[currentOptional] = arg;
      }

      // The next value can be either an option or an item
      mode = 'both';
    } else if (arg === 'test') {
      this.test = true;
    } else if (['both', 'item'].includes(mode)) {
      // item arguments
      this.items.push(arg);

      // The next value must be an item
      mode = 'item';
    } else {
      // Bad case, abort
      this.abort(usage);
    }
  }
}
module.exports = CLI;

CLI.prototype.abort = function(msg) {
  console.error(msg);
  process.exit(1);
};

CLI.prototype.benchmarks = function() {
  const paths = [];

  if (this.items.includes('all')) {
    this.items = Object.keys(benchmarks);
  }

  for (const category of this.items) {
    if (benchmarks[category] === undefined) {
      console.error(`The "${category}" category does not exist.`);
      process.exit(1);
    }
    for (const scripts of benchmarks[category]) {
      if (this.shouldSkip(scripts)) continue;

      paths.push(path.join(category, scripts));
    }
  }

  return paths;
};

CLI.prototype.shouldSkip = function(scripts) {
  const filters = this.optional.filter || [];
  const excludes = this.optional.exclude || [];
  let skip = filters.length > 0;

  for (const filter of filters) {
    if (scripts.lastIndexOf(filter) !== -1) {
      skip = false;
    }
  }

  for (const exclude of excludes) {
    if (scripts.lastIndexOf(exclude) !== -1) {
      skip = true;
    }
  }

  return skip;
};
