// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "fuzzers/tint_spirv_tools_fuzzer/cli.h"

#include <fstream>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "fuzzers/tint_spirv_tools_fuzzer/util.h"
#include "source/opt/build_module.h"

namespace tint {
namespace fuzzers {
namespace spvtools_fuzzer {
namespace {

const char* const kMutatorParameters = R"(
Mutators' parameters:

  -tint_donors=
                       A path to the text file with a list of paths to the
                       SPIR-V donor files. Check out the doc for the spirv-fuzz
                       to learn more about donor binaries. Donors are not used
                       by default.

  -tint_enable_all_fuzzer_passes=
                       Whether to use all fuzzer passes or a randomly selected subset
                       of them. This must be one of `true` or `false` (without `).
                       By default it's `false`.

  -tint_enable_all_reduce_passes=
                       Whether to use all reduction passes or a randomly selected subset
                       of them. This must be one of `true` or `false` (without `).
                       By default it's `false`.

  -tint_opt_batch_size=
                       The maximum number of spirv-opt optimizations that
                       will be applied in a single mutation session (i.e.
                       a call to LLVMFuzzerCustomMutator). This must fit in
                       uint32_t. By default it's 6.

  -tint_reduction_batch_size=
                       The maximum number of spirv-reduce reductions that
                       will be applied in a single mutation session (i.e.
                       a call to LLVMFuzzerCustomMutator). This must fit in
                       uint32_t. By default it's 3.

  -tint_repeated_pass_strategy=
                       The strategy that will be used to recommend the next fuzzer
                       pass. This must be one of `simple`, `looped` or `random`
                       (without `). By default it's `simple`. Check out the doc for
                       spirv-fuzz to learn more.

  -tint_transformation_batch_size=
                       The maximum number of spirv-fuzz transformations
                       that will be applied during a single mutation
                       session (i.e. a call to LLVMFuzzerCustomMutator).
                       This must fit in uint32_t. By default it's 3.

  -tint_validate_after_each_fuzzer_pass=
                       Whether to validate SPIR-V binary after each fuzzer pass.
                       This must be one of `true` or `false` (without `).
                       By default it's `true`. Switch this to `false` if you experience
                       bad performance.

  -tint_validate_after_each_opt_pass=
                       Whether to validate SPIR-V binary after each optimization pass.
                       This must be one of `true` or `false` (without `).
                       By default it's `true`. Switch this to `false` if you experience
                       bad performance.

  -tint_validate_after_each_reduce_pass=
                       Whether to validate SPIR-V binary after each reduction pass.
                       This must be one of `true` or `false` (without `).
                       By default it's `true`. Switch this to `false` if you experience
                       bad performance.
)";

const char* const kFuzzerHelpMessage = R"(
This fuzzer uses SPIR-V binaries to fuzz the Tint compiler. It uses SPIRV-Tools
to mutate those binaries. The fuzzer works on a corpus of SPIR-V shaders.
For each shader from the corpus it uses one of `spirv-fuzz`, `spirv-reduce` or
`spirv-opt` to mutate it and then runs the shader through the Tint compiler in
two steps:
- Converts the mutated shader to WGSL.
- Converts WGSL to some target language specified in the CLI arguments.

Below is a list of all supported parameters for this fuzzer. You may want to
run it with -help=1 to check out libfuzzer parameters.

Fuzzer parameters:

  -tint_error_dir
                       The directory that will be used to output invalid SPIR-V
                       binaries to. This is especially useful during debugging
                       mutators. The directory must have the following subdirectories:
                       - spv/ - will be used to output errors, produced during
                         the conversion from the SPIR-V to WGSL.
                       - wgsl/ - will be used to output errors, produced during
                         the conversion from the WGSL to `--fuzzing_target`.
                       - mutator/ - will be used to output errors, produced by
                         the mutators.
                       By default invalid files are not printed out.

  -tint_fuzzing_target
                       The type of backend to target during fuzzing. This must
                       be one or a combination of `wgsl`, `spv`, `msl` or `hlsl`
                       (without `) separated by commas. By default it's
                       `wgsl,spv,msl,hlsl`.

  -tint_help
                       Show this message. Note that there is also a -help=1
                       parameter that will display libfuzzer's help message.

  -tint_mutator_cache_size=
                       The maximum size of the cache that stores
                       mutation sessions. This must fit in uint32_t.
                       By default it's 20.

  -tint_mutator_type=
                       Determines types of the mutators to run. This must be one or
                       a combination of `fuzz`, `opt`, `reduce` (without `) separated by
                       comma. If a combination is specified, each element in the
                       combination will have an equal chance of mutating a SPIR-V
                       binary during a mutation session (i.e. if no mutator exists
                       for that binary in the mutator cache). By default, the
                       parameter's value is `fuzz,opt,reduce`.
)";

const char* const kMutatorDebuggerHelpMessage = R"(
This tool is used to debug *mutators*. It uses CLI arguments similar to the
ones used by the fuzzer. To debug some mutator you just need to specify the
mutator type, the seed and the path to the SPIR-V binary that triggered the
error. This tool will run the mutator on the binary until the error is
produced or the mutator returns `kLimitReached`.

Note that this is different from debugging the fuzzer by specifying input
files to test. The difference is that the latter will not execute any
mutator (it will only run the LLVMFuzzerTestOneInput function) whereas this
tool is useful when one of the SPIRV-Tools mutators crashes or produces an
invalid binary in LLVMFuzzerCustomMutator.

Debugger parameters:

  --help
                       Show this message.

  --mutator_type=
                       Determines the type of the mutator to debug. This must be
                       one of `fuzz`, `reduce` or `opt` (without `). This parameter
                       is REQUIRED.

  --original_binary=
                       The path to the SPIR-V binary that the faulty mutator was
                       initialized with. This will be dumped on errors by the fuzzer
                       if `--error_dir` is specified. This parameter is REQUIRED.

  --seed=
                       The seed for the random number generator that was used to
                       initialize the mutator. This value is usually printed to
                       the console when the mutator produces an invalid binary.
                       It is also dumped into the log file if `--error_dir` is
                       specified. This must fit in uint32_t. This parameter is
                       REQUIRED.
)";

void PrintHelpMessage(const char* help_message) {
  std::cout << help_message << std::endl << kMutatorParameters << std::endl;
}

[[noreturn]] void InvalidParameter(const char* help_message,
                                   const char* param) {
  std::cout << "Invalid value for " << param << std::endl;
  PrintHelpMessage(help_message);
  exit(1);
}

bool ParseUint32(const char* param, uint32_t* out) {
  uint64_t value = static_cast<uint64_t>(strtoul(param, nullptr, 10));
  if (value > static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
    return false;
  }
  *out = static_cast<uint32_t>(value);
  return true;
}

std::vector<spvtools::fuzz::fuzzerutil::ModuleSupplier> ParseDonors(
    const char* file_name) {
  std::ifstream fin(file_name);
  if (!fin) {
    std::cout << "Can't open donors list file: " << file_name << std::endl;
    exit(1);
  }

  std::vector<spvtools::fuzz::fuzzerutil::ModuleSupplier> result;
  for (std::string donor_file_name; fin >> donor_file_name;) {
    if (!std::ifstream(donor_file_name)) {
      std::cout << "Can't open donor file: " << donor_file_name << std::endl;
      exit(1);
    }

    result.emplace_back([donor_file_name] {
      std::vector<uint32_t> binary;
      if (!util::ReadBinary(donor_file_name, &binary)) {
        std::cout << "Failed to read donor from: " << donor_file_name
                  << std::endl;
        exit(1);
      }
      return spvtools::BuildModule(
          kDefaultTargetEnv, spvtools::fuzz::fuzzerutil::kSilentMessageConsumer,
          binary.data(), binary.size());
    });
  }

  return result;
}

bool ParseRepeatedPassStrategy(const char* param,
                               spvtools::fuzz::RepeatedPassStrategy* out) {
  if (!strcmp(param, "simple")) {
    *out = spvtools::fuzz::RepeatedPassStrategy::kSimple;
  } else if (!strcmp(param, "looped")) {
    *out = spvtools::fuzz::RepeatedPassStrategy::kLoopedWithRecommendations;
  } else if (!strcmp(param, "random")) {
    *out = spvtools::fuzz::RepeatedPassStrategy::kRandomWithRecommendations;
  } else {
    return false;
  }
  return true;
}

bool ParseBool(const char* param, bool* out) {
  if (!strcmp(param, "true")) {
    *out = true;
  } else if (!strcmp(param, "false")) {
    *out = false;
  } else {
    return false;
  }
  return true;
}

bool ParseMutatorType(const char* param, MutatorType* out) {
  if (!strcmp(param, "fuzz")) {
    *out = MutatorType::kFuzz;
  } else if (!strcmp(param, "opt")) {
    *out = MutatorType::kOpt;
  } else if (!strcmp(param, "reduce")) {
    *out = MutatorType::kReduce;
  } else {
    return false;
  }
  return true;
}

bool ParseFuzzingTarget(const char* param, FuzzingTarget* out) {
  if (!strcmp(param, "wgsl")) {
    *out = FuzzingTarget::kWgsl;
  } else if (!strcmp(param, "spv")) {
    *out = FuzzingTarget::kSpv;
  } else if (!strcmp(param, "msl")) {
    *out = FuzzingTarget::kMsl;
  } else if (!strcmp(param, "hlsl")) {
    *out = FuzzingTarget::kHlsl;
  } else {
    return false;
  }
  return true;
}

bool HasPrefix(const char* str, const char* prefix) {
  return strncmp(str, prefix, strlen(prefix)) == 0;
}

bool ParseMutatorCliParam(const char* param,
                          const char* help_message,
                          MutatorCliParams* out) {
  if (HasPrefix(param, "-tint_transformation_batch_size=")) {
    if (!ParseUint32(param + sizeof("-tint_transformation_batch_size=") - 1,
                     &out->transformation_batch_size)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_reduction_batch_size=")) {
    if (!ParseUint32(param + sizeof("-tint_reduction_batch_size=") - 1,
                     &out->reduction_batch_size)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_opt_batch_size=")) {
    if (!ParseUint32(param + sizeof("-tint_opt_batch_size=") - 1,
                     &out->opt_batch_size)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_donors=")) {
    out->donors = ParseDonors(param + sizeof("-tint_donors=") - 1);
  } else if (HasPrefix(param, "-tint_repeated_pass_strategy=")) {
    if (!ParseRepeatedPassStrategy(
            param + sizeof("-tint_repeated_pass_strategy=") - 1,
            &out->repeated_pass_strategy)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_enable_all_fuzzer_passes=")) {
    if (!ParseBool(param + sizeof("-tint_enable_all_fuzzer_passes=") - 1,
                   &out->enable_all_fuzzer_passes)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_enable_all_reduce_passes=")) {
    if (!ParseBool(param + sizeof("-tint_enable_all_reduce_passes=") - 1,
                   &out->enable_all_reduce_passes)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_validate_after_each_opt_pass=")) {
    if (!ParseBool(param + sizeof("-tint_validate_after_each_opt_pass=") - 1,
                   &out->validate_after_each_opt_pass)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_validate_after_each_fuzzer_pass=")) {
    if (!ParseBool(param + sizeof("-tint_validate_after_each_fuzzer_pass=") - 1,
                   &out->validate_after_each_fuzzer_pass)) {
      InvalidParameter(help_message, param);
    }
  } else if (HasPrefix(param, "-tint_validate_after_each_reduce_pass=")) {
    if (!ParseBool(param + sizeof("-tint_validate_after_each_reduce_pass=") - 1,
                   &out->validate_after_each_reduce_pass)) {
      InvalidParameter(help_message, param);
    }
  } else {
    return false;
  }
  return true;
}

}  // namespace

FuzzerCliParams ParseFuzzerCliParams(int* argc, char** argv) {
  FuzzerCliParams cli_params;
  const auto* help_message = kFuzzerHelpMessage;
  auto help = false;

  for (int i = *argc - 1; i > 0; --i) {
    auto param = argv[i];
    auto recognized_param = true;

    if (HasPrefix(param, "-tint_mutator_cache_size=")) {
      if (!ParseUint32(param + sizeof("-tint_mutator_cache_size=") - 1,
                       &cli_params.mutator_cache_size)) {
        InvalidParameter(help_message, param);
      }
    } else if (HasPrefix(param, "-tint_mutator_type=")) {
      auto result = MutatorType::kNone;

      std::stringstream ss(param + sizeof("-tint_mutator_type=") - 1);
      for (std::string value; std::getline(ss, value, ',');) {
        auto out = MutatorType::kNone;
        if (!ParseMutatorType(value.c_str(), &out)) {
          InvalidParameter(help_message, param);
        }
        result = result | out;
      }

      if (result == MutatorType::kNone) {
        InvalidParameter(help_message, param);
      }

      cli_params.mutator_type = result;
    } else if (HasPrefix(param, "-tint_fuzzing_target=")) {
      auto result = FuzzingTarget::kNone;

      std::stringstream ss(param + sizeof("-tint_fuzzing_target=") - 1);
      for (std::string value; std::getline(ss, value, ',');) {
        auto tmp = FuzzingTarget::kNone;
        if (!ParseFuzzingTarget(value.c_str(), &tmp)) {
          InvalidParameter(help_message, param);
        }
        result = result | tmp;
      }

      if (result == FuzzingTarget::kNone) {
        InvalidParameter(help_message, param);
      }

      cli_params.fuzzing_target = result;
    } else if (HasPrefix(param, "-tint_error_dir=")) {
      cli_params.error_dir = param + sizeof("-tint_error_dir=") - 1;
    } else if (!strcmp(param, "-tint_help")) {
      help = true;
    } else {
      recognized_param = ParseMutatorCliParam(param, help_message,
                                              &cli_params.mutator_params);
    }

    if (recognized_param) {
      // Remove the recognized parameter from the list of all parameters by
      // swapping it with the last one. This will suppress warnings in the
      // libFuzzer about unrecognized parameters. By default, libFuzzer thinks
      // that all user-defined parameters start with two dashes. However, we are
      // forced to use a single one to make the fuzzer compatible with the
      // ClusterFuzz.
      std::swap(argv[i], argv[*argc - 1]);
      *argc -= 1;
    }
  }

  if (help) {
    PrintHelpMessage(help_message);
    exit(0);
  }

  return cli_params;
}

MutatorDebuggerCliParams ParseMutatorDebuggerCliParams(
    int argc,
    const char* const* argv) {
  MutatorDebuggerCliParams cli_params;
  bool seed_param_present = false;
  bool original_binary_param_present = false;
  bool mutator_type_param_present = false;
  const auto* help_message = kMutatorDebuggerHelpMessage;
  auto help = false;

  for (int i = 0; i < argc; ++i) {
    auto param = argv[i];
    ParseMutatorCliParam(param, help_message, &cli_params.mutator_params);

    if (HasPrefix(param, "--mutator_type=")) {
      if (!ParseMutatorType(param + sizeof("--mutator_type=") - 1,
                            &cli_params.mutator_type)) {
        InvalidParameter(help_message, param);
      }
      mutator_type_param_present = true;
    } else if (HasPrefix(param, "--original_binary=")) {
      if (!util::ReadBinary(param + sizeof("--original_binary=") - 1,
                            &cli_params.original_binary)) {
        InvalidParameter(help_message, param);
      }
      original_binary_param_present = true;
    } else if (HasPrefix(param, "--seed=")) {
      if (!ParseUint32(param + sizeof("--seed=") - 1, &cli_params.seed)) {
        InvalidParameter(help_message, param);
      }
      seed_param_present = true;
    } else if (!strcmp(param, "--help")) {
      help = true;
    }
  }

  if (help) {
    PrintHelpMessage(help_message);
    exit(0);
  }

  std::pair<bool, const char*> required_params[] = {
      {seed_param_present, "--seed"},
      {original_binary_param_present, "--original_binary"},
      {mutator_type_param_present, "--mutator_type"}};

  for (auto required_param : required_params) {
    if (!required_param.first) {
      std::cout << required_param.second << " is missing" << std::endl;
      exit(1);
    }
  }

  return cli_params;
}

}  // namespace spvtools_fuzzer
}  // namespace fuzzers
}  // namespace tint
