// Copyright (c) 2018 Google LLC
//
// 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 SOURCE_REDUCE_REDUCER_H_
#define SOURCE_REDUCE_REDUCER_H_

#include <functional>
#include <string>

#include "source/reduce/reduction_pass.h"
#include "spirv-tools/libspirv.hpp"

namespace spvtools {
namespace reduce {

// This class manages the process of applying a reduction -- parameterized by a
// number of reduction passes and an interestingness test, to a SPIR-V binary.
class Reducer {
 public:
  // Possible statuses that can result from running a reduction.
  enum ReductionResultStatus {
    kInitialStateNotInteresting,
    kReachedStepLimit,
    kComplete,
    kInitialStateInvalid,

    // Returned when the fail-on-validation-error option is set and a
    // reduction step yields a state that fails validation.
    kStateInvalid,
  };

  // The type for a function that will take a binary and return true if and
  // only if the binary is deemed interesting. (The function also takes an
  // integer argument that will be incremented each time the function is
  // called; this is for debugging purposes).
  //
  // The notion of "interesting" depends on what properties of the binary or
  // tools that process the binary we are trying to maintain during reduction.
  using InterestingnessFunction =
      std::function<bool(const std::vector<uint32_t>&, uint32_t)>;

  // Constructs an instance with the given target |target_env|, which is used to
  // decode the binary to be reduced later.
  //
  // The constructed instance will have an empty message consumer, which just
  // ignores all messages from the library. Use SetMessageConsumer() to supply
  // one if messages are of concern.
  //
  // The constructed instance also needs to have an interestingness function
  // set and some reduction passes added to it in order to be useful.
  explicit Reducer(spv_target_env target_env);

  // Disables copy/move constructor/assignment operations.
  Reducer(const Reducer&) = delete;
  Reducer(Reducer&&) = delete;
  Reducer& operator=(const Reducer&) = delete;
  Reducer& operator=(Reducer&&) = delete;

  // Destructs this instance.
  ~Reducer();

  // Sets the message consumer to the given |consumer|. The |consumer| will be
  // invoked once for each message communicated from the library.
  void SetMessageConsumer(MessageConsumer consumer);

  // Sets the function that will be used to decide whether a reduced binary
  // turned out to be interesting.
  void SetInterestingnessFunction(
      InterestingnessFunction interestingness_function);

  // Adds all default reduction passes.
  void AddDefaultReductionPasses();

  // Adds a reduction pass based on the given finder to the sequence of passes
  // that will be iterated over.
  void AddReductionPass(std::unique_ptr<ReductionOpportunityFinder>&& finder);

  // Adds a cleanup reduction pass based on the given finder to the sequence of
  // passes that will run after other passes.
  void AddCleanupReductionPass(
      std::unique_ptr<ReductionOpportunityFinder>&& finder);

  // Reduces the given SPIR-V module |binary_out|.
  // The reduced binary ends up in |binary_out|.
  // A status is returned.
  ReductionResultStatus Run(std::vector<uint32_t>&& binary_in,
                            std::vector<uint32_t>* binary_out,
                            spv_const_reducer_options options,
                            spv_validator_options validator_options);

 private:
  static bool ReachedStepLimit(uint32_t current_step,
                               spv_const_reducer_options options);

  ReductionResultStatus RunPasses(
      std::vector<std::unique_ptr<ReductionPass>>* passes,
      spv_const_reducer_options options,
      spv_validator_options validator_options, const SpirvTools& tools,
      std::vector<uint32_t>* current_binary, uint32_t* reductions_applied);

  const spv_target_env target_env_;
  MessageConsumer consumer_;
  InterestingnessFunction interestingness_function_;
  std::vector<std::unique_ptr<ReductionPass>> passes_;
  std::vector<std::unique_ptr<ReductionPass>> cleanup_passes_;
};

}  // namespace reduce
}  // namespace spvtools

#endif  // SOURCE_REDUCE_REDUCER_H_
