// 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/spirv_opt_mutator.h"

#include <fstream>
#include <iostream>
#include <unordered_set>
#include <utility>

#include "fuzzers/tint_spirv_tools_fuzzer/util.h"
#include "spirv-tools/optimizer.hpp"

namespace tint {
namespace fuzzers {
namespace spvtools_fuzzer {

SpirvOptMutator::SpirvOptMutator(spv_target_env target_env,
                                 uint32_t seed,
                                 std::vector<uint32_t> binary,
                                 bool validate_after_each_opt,
                                 uint32_t opt_batch_size)
    : num_executions_(0),
      is_valid_(true),
      target_env_(target_env),
      original_binary_(std::move(binary)),
      seed_(seed),
      opt_passes_({"--combine-access-chains",
                   "--loop-unroll",
                   "--merge-blocks",
                   "--cfg-cleanup",
                   "--eliminate-dead-functions",
                   "--merge-return",
                   "--wrap-opkill",
                   "--eliminate-dead-code-aggressive",
                   "--if-conversion",
                   "--eliminate-local-single-store",
                   "--eliminate-local-single-block",
                   "--eliminate-dead-branches",
                   "--scalar-replacement=0",
                   "--eliminate-dead-inserts",
                   "--eliminate-dead-members",
                   "--simplify-instructions",
                   "--private-to-local",
                   "--ssa-rewrite",
                   "--ccp",
                   "--reduce-load-size",
                   "--vector-dce",
                   "--scalar-replacement=100",
                   "--inline-entry-points-exhaustive",
                   "--redundancy-elimination",
                   "--convert-local-access-chains",
                   "--copy-propagate-arrays",
                   "--fix-storage-class"}),
      optimized_binary_(),
      validate_after_each_opt_(validate_after_each_opt),
      opt_batch_size_(opt_batch_size),
      rng_(seed) {
  assert(spvtools::SpirvTools(target_env).Validate(original_binary_) &&
         "Initial binary is invalid");
  assert(!opt_passes_.empty() && "Must be at least one pass");
}

SpirvOptMutator::Result SpirvOptMutator::Mutate() {
  assert(is_valid_ && "The optimizer is not longer valid");

  const uint32_t kMaxNumExecutions = 100;
  const uint32_t kMaxNumStuck = 10;

  if (num_executions_ == kMaxNumExecutions) {
    // We've applied this mutator many times already. Indicate to the user that
    // it might be better to try a different mutator.
    return {Status::kLimitReached, false};
  }

  num_executions_++;

  // Get the input binary. If this is the first time we run this mutator, use
  // the `original_binary_`. Otherwise, one of the following will be true:
  // - the `optimized_binary_` is not empty.
  // - the previous call to the `Mutate` method returned `kStuck`.
  auto binary = num_executions_ == 1 ? original_binary_ : optimized_binary_;
  optimized_binary_.clear();

  assert(!binary.empty() && "Can't run the optimizer on an empty binary");

  // Number of times spirv-opt wasn't able to produce any new result.
  uint32_t num_stuck = 0;
  do {
    // Randomly select `opt_batch_size` optimization passes. If `opt_batch_size`
    // is equal to 0, we will use the number of passes equal to the number of
    // all available passes.
    auto num_of_passes = opt_batch_size_ ? opt_batch_size_ : opt_passes_.size();
    std::vector<std::string> passes;

    while (passes.size() < num_of_passes) {
      auto idx = std::uniform_int_distribution<size_t>(
          0, opt_passes_.size() - 1)(rng_);
      passes.push_back(opt_passes_[idx]);
    }

    // Run the `binary` into the `optimized_binary_`.
    spvtools::Optimizer optimizer(target_env_);
    optimizer.SetMessageConsumer(util::GetBufferMessageConsumer(&errors_));
    optimizer.SetValidateAfterAll(validate_after_each_opt_);
    optimizer.RegisterPassesFromFlags(passes);
    if (!optimizer.Run(binary.data(), binary.size(), &optimized_binary_)) {
      is_valid_ = false;
      return {Status::kInvalid, true};
    }
  } while (optimized_binary_.empty() && ++num_stuck < kMaxNumStuck);

  return {optimized_binary_.empty() ? Status::kStuck : Status::kComplete,
          !optimized_binary_.empty()};
}

std::vector<uint32_t> SpirvOptMutator::GetBinary() const {
  return optimized_binary_;
}

std::string SpirvOptMutator::GetErrors() const {
  return errors_.str();
}

void SpirvOptMutator::LogErrors(const std::string* path, uint32_t count) const {
  auto message = GetErrors();
  std::cout << count << " | SpirvOptMutator (seed: " << seed_ << ")"
            << std::endl;
  std::cout << message << std::endl;

  if (path) {
    auto prefix = *path + std::to_string(count);

    // Write errors to file.
    std::ofstream(prefix + ".opt.log") << "seed: " << seed_ << std::endl
                                       << message << std::endl;

    // Write the invalid SPIR-V binary.
    util::WriteBinary(prefix + ".opt.invalid.spv", optimized_binary_);

    // Write the original SPIR-V binary.
    util::WriteBinary(prefix + ".opt.original.spv", original_binary_);
  }
}

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