// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Description of this file.
 */

'use strict';

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

const program = require('commander');

const corpus = require('./corpus.js');
const differentialScriptMutator = require('./differential_script_mutator.js');
const random = require('./random.js');
const scriptMutator = require('./script_mutator.js');
const sourceHelpers = require('./source_helpers.js');

// Maximum number of test inputs to use for one fuzz test.
const MAX_TEST_INPUTS_PER_TEST = 10;

// Base implementations for default or differential fuzzing.
const SCRIPT_MUTATORS = {
  default: scriptMutator.ScriptMutator,
  foozzie: differentialScriptMutator.DifferentialScriptMutator,
};

function getRandomInputs(primaryCorpus, secondaryCorpora, count) {
  count = random.randInt(2, count);

  // Choose 40%-80% of inputs from primary corpus.
  const primaryCount = Math.floor(random.uniform(0.4, 0.8) * count);
  count -= primaryCount;

  let inputs = primaryCorpus.getRandomTestcases(primaryCount);

  // Split remainder equally between the secondary corpora.
  const secondaryCount = Math.floor(count / secondaryCorpora.length);

  for (let i = 0; i < secondaryCorpora.length; i++) {
    let currentCount = secondaryCount;
    if (i == secondaryCorpora.length - 1) {
      // Last one takes the remainder.
      currentCount = count;
    }

    count -= currentCount;
    if (currentCount) {
      inputs = inputs.concat(
          secondaryCorpora[i].getRandomTestcases(currentCount));
    }
  }

  return random.shuffle(inputs);
}

function collect(value, total) {
  total.push(value);
  return total;
}

function overrideSettings(settings, settingOverrides) {
  for (const setting of settingOverrides) {
    const parts = setting.split('=');
    settings[parts[0]] = parseFloat(parts[1]);
  }
}

function* randomInputGen(engine) {
  const inputDir = path.resolve(program.input_dir);

  const v8Corpus = new corpus.Corpus(inputDir, 'v8');
  const chakraCorpus = new corpus.Corpus(inputDir, 'chakra');
  const spiderMonkeyCorpus = new corpus.Corpus(inputDir, 'spidermonkey');
  const jscCorpus = new corpus.Corpus(inputDir, 'WebKit/JSTests');
  const crashTestsCorpus = new corpus.Corpus(inputDir, 'CrashTests');

  for (let i = 0; i < program.no_of_files; i++) {
    let inputs;
    if (engine === 'V8') {
      inputs = getRandomInputs(
          v8Corpus,
          random.shuffle([chakraCorpus, spiderMonkeyCorpus, jscCorpus,
                          crashTestsCorpus, v8Corpus]),
          MAX_TEST_INPUTS_PER_TEST);
    } else if (engine == 'chakra') {
      inputs = getRandomInputs(
          chakraCorpus,
          random.shuffle([v8Corpus, spiderMonkeyCorpus, jscCorpus,
                          crashTestsCorpus]),
          MAX_TEST_INPUTS_PER_TEST);
    } else if (engine == 'spidermonkey') {
      inputs = getRandomInputs(
          spiderMonkeyCorpus,
          random.shuffle([v8Corpus, chakraCorpus, jscCorpus,
                          crashTestsCorpus]),
          MAX_TEST_INPUTS_PER_TEST);
    } else {
      inputs = getRandomInputs(
          jscCorpus,
          random.shuffle([chakraCorpus, spiderMonkeyCorpus, v8Corpus,
                          crashTestsCorpus]),
          MAX_TEST_INPUTS_PER_TEST);
    }

    if (inputs.length > 0) {
      yield inputs;
    }
  }
}

function* corpusInputGen() {
  const inputCorpus = new corpus.Corpus(
      path.resolve(program.input_dir),
      program.mutate_corpus,
      program.extra_strict);
  for (const input of inputCorpus.getAllTestcases()) {
    yield [input];
  }
}

function* enumerate(iterable) {
  let i = 0;
  for (const value of iterable) {
    yield [i, value];
    i++;
  }
}

function main() {
  Error.stackTraceLimit = Infinity;

  program
    .version('0.0.1')
    .option('-i, --input_dir <path>', 'Input directory.')
    .option('-o, --output_dir <path>', 'Output directory.')
    .option('-n, --no_of_files <n>', 'Output directory.', parseInt)
    .option('-c, --mutate_corpus <name>', 'Mutate single files in a corpus.')
    .option('-e, --extra_strict', 'Additionally parse files in strict mode.')
    .option('-m, --mutate <path>', 'Mutate a file and output results.')
    .option('-s, --setting [setting]', 'Settings overrides.', collect, [])
    .option('-v, --verbose', 'More verbose printing.')
    .option('-z, --zero_settings', 'Zero all settings.')
    .parse(process.argv);

  const settings = scriptMutator.defaultSettings();
  if (program.zero_settings) {
    for (const key of Object.keys(settings)) {
      settings[key] = 0.0;
    }
  }

  if (program.setting.length > 0) {
    overrideSettings(settings, program.setting);
  }

  let app_name = process.env.APP_NAME;
  if (app_name && app_name.endsWith('.exe')) {
    app_name = app_name.substr(0, app_name.length - 4);
  }

  if (app_name === 'd8' || app_name === 'v8_foozzie.py') {
    // V8 supports running the raw d8 executable or the differential fuzzing
    // harness 'foozzie'.
    settings.engine = 'V8';
  } else if (app_name === 'ch') {
    settings.engine = 'chakra';
  } else if (app_name === 'js') {
    settings.engine = 'spidermonkey';
  } else if (app_name === 'jsc') {
    settings.engine = 'jsc';
  } else {
    console.log('ERROR: Invalid APP_NAME');
    process.exit(1);
  }

  const mode = process.env.FUZZ_MODE || 'default';
  assert(mode in SCRIPT_MUTATORS, `Unknown mode ${mode}`);
  const mutator = new SCRIPT_MUTATORS[mode](settings);

  if (program.mutate) {
    const absPath = path.resolve(program.mutate);
    const baseDir = path.dirname(absPath);
    const fileName = path.basename(absPath);
    const input = sourceHelpers.loadSource(
        baseDir, fileName, program.extra_strict);
    const mutated = mutator.mutateMultiple([input]);
    console.log(mutated.code);
    return;
  }

  let inputGen;

  if (program.mutate_corpus) {
    inputGen = corpusInputGen();
  } else {
    inputGen = randomInputGen(settings.engine);
  }

  for (const [i, inputs] of enumerate(inputGen)) {
    const outputPath = path.join(program.output_dir, 'fuzz-' + i + '.js');

    const start = Date.now();
    const paths = inputs.map(input => input.relPath);

    try {
      const mutated = mutator.mutateMultiple(inputs);
      fs.writeFileSync(outputPath, mutated.code);

      if (settings.engine === 'V8' && mutated.flags && mutated.flags.length > 0) {
        const flagsPath = path.join(program.output_dir, 'flags-' + i + '.js');
        fs.writeFileSync(flagsPath, mutated.flags.join(' '));
      }
    } catch (e) {
      if (e.message.startsWith('ENOSPC')) {
        console.log('ERROR: No space left. Bailing out...');
        console.log(e);
        return;
      }
      console.log(`ERROR: Exception during mutate: ${paths}`);
      console.log(e);
      continue;
    } finally {
      if (program.verbose) {
        const duration = Date.now() - start;
        console.log(`Mutating ${paths} took ${duration} ms.`);
      }
    }
    if ((i + 1)  % 10 == 0) {
      console.log('Up to ', i + 1);
    }
  }
}

main();
