// 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.

#ifndef FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_
#define FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_

#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "fuzzers/random_generator.h"
#include "fuzzers/tint_spirv_tools_fuzzer/mutator.h"

#include "source/reduce/reduction_opportunity_finder.h"

namespace tint {
namespace fuzzers {
namespace spvtools_fuzzer {

/// Mutates SPIR-V binary by running spirv-reduce tool.
///
/// The initial `binary` must be valid according to `target_env`. Applies at
/// most `reductions_batch_size` reductions at a time. This parameter is ignored
/// if its value is 0. Uses a random subset of reduction opportunity finders by
/// default. This can be overridden with the `enable_all_reductions` parameter.
class SpirvReduceMutator : public Mutator {
 public:
  /// Constructor.
  /// @param target_env - the target environment for the `binary`.
  /// @param binary - SPIR-V binary. Must be valid.
  /// @param seed - the seed for the RNG.
  /// @param reductions_batch_size - the number of reduction passes that will be
  ///     applied during a single call to `Mutate`. If it's equal to 0 then we
  ///     apply the passes until we reach the threshold for the total number of
  ///     applied passes.
  /// @param enable_all_reductions - whether to use all reduction passes or only
  ///     a randomly selected subset of them.
  /// @param validate_after_each_reduction - whether to validate after each
  ///     applied reduction.
  SpirvReduceMutator(spv_target_env target_env,
                     std::vector<uint32_t> binary,
                     uint32_t seed,
                     uint32_t reductions_batch_size,
                     bool enable_all_reductions,
                     bool validate_after_each_reduction);

  Result Mutate() override;
  std::vector<uint32_t> GetBinary() const override;
  void LogErrors(const std::string* path, uint32_t count) const override;
  std::string GetErrors() const override;

 private:
  template <typename T, typename... Args>
  void MaybeAddFinder(Args&&... args) {
    if (enable_all_reductions_ || generator_.GetBool()) {
      finders_.push_back(std::make_unique<T>(std::forward<Args>(args)...));
    }
  }

  template <typename T>
  T* GetRandomElement(std::vector<T>* arr) {
    assert(!arr->empty() && "Can't get random element from an empty vector");
    auto index = generator_.GetUInt32(static_cast<uint32_t>(arr->size()));
    return &(*arr)[index];
  }

  template <typename T>
  T* GetRandomElement(std::vector<std::unique_ptr<T>>* arr) {
    assert(!arr->empty() && "Can't get random element from an empty vector");
    auto index = generator_.GetUInt32(static_cast<uint32_t>(arr->size()));
    return (*arr)[index].get();
  }

  bool ApplyReduction(
      spvtools::reduce::ReductionOpportunity* reduction_opportunity);

  // The SPIR-V binary that is being reduced.
  std::unique_ptr<spvtools::opt::IRContext> ir_context_;

  // The selected subset of reduction opportunity finders.
  std::vector<std::unique_ptr<spvtools::reduce::ReductionOpportunityFinder>>
      finders_;

  // Random number generator initialized with `seed_`.
  RandomGenerator generator_;

  // All the errors produced by the reducer.
  std::stringstream errors_;

  // Whether the last call to the `Mutate` method produced the valid binary.
  bool is_valid_;

  // The number of reductions to apply on a single call to `Mutate`.
  const uint32_t reductions_batch_size_;

  // The total number of applied reductions.
  uint32_t total_applied_reductions_;

  // Whether we want to use all the reduction opportunity finders and not just a
  // subset of them.
  const bool enable_all_reductions_;

  // Whether we want to validate all the binary after each reduction.
  const bool validate_after_each_reduction_;

  // The original binary that was used to initialize this mutator.
  // Useful for debugging.
  const std::vector<uint32_t> original_binary_;

  // The seed that was used to initialize the random number generator.
  // Useful for debugging.
  const uint32_t seed_;
};

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

#endif  // FUZZERS_TINT_SPIRV_TOOLS_FUZZER_SPIRV_REDUCE_MUTATOR_H_
