// Copyright (c) 2020 Vasyl Teliman
//
// 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 <numeric>
#include <vector>

#include "source/fuzz/fuzzer_context.h"
#include "source/fuzz/fuzzer_pass_permute_function_parameters.h"
#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/instruction_descriptor.h"
#include "source/fuzz/transformation_permute_function_parameters.h"

namespace spvtools {
namespace fuzz {

FuzzerPassPermuteFunctionParameters::FuzzerPassPermuteFunctionParameters(
    opt::IRContext* ir_context, TransformationContext* transformation_context,
    FuzzerContext* fuzzer_context,
    protobufs::TransformationSequence* transformations)
    : FuzzerPass(ir_context, transformation_context, fuzzer_context,
                 transformations) {}

FuzzerPassPermuteFunctionParameters::~FuzzerPassPermuteFunctionParameters() =
    default;

void FuzzerPassPermuteFunctionParameters::Apply() {
  for (const auto& function : *GetIRContext()->module()) {
    uint32_t function_id = function.result_id();

    // Skip the function if it is an entry point
    if (fuzzerutil::FunctionIsEntryPoint(GetIRContext(), function_id)) {
      continue;
    }

    if (!GetFuzzerContext()->ChoosePercentage(
            GetFuzzerContext()->GetChanceOfPermutingParameters())) {
      continue;
    }

    // Compute permutation for parameters
    auto* function_type =
        fuzzerutil::GetFunctionType(GetIRContext(), &function);
    assert(function_type && "Function type is null");

    // Don't take return type into account
    uint32_t arg_size = function_type->NumInOperands() - 1;

    // Create a vector, fill it with [0, n-1] values and shuffle it
    std::vector<uint32_t> permutation(arg_size);
    std::iota(permutation.begin(), permutation.end(), 0);
    GetFuzzerContext()->Shuffle(&permutation);

    // Create a new OpFunctionType instruction with permuted arguments
    // if needed
    auto result_type_id = function_type->GetSingleWordInOperand(0);
    std::vector<uint32_t> argument_ids;

    for (auto index : permutation) {
      // +1 to take function's return type into account
      argument_ids.push_back(function_type->GetSingleWordInOperand(index + 1));
    }

    // Apply our transformation
    ApplyTransformation(TransformationPermuteFunctionParameters(
        function_id, FindOrCreateFunctionType(result_type_id, argument_ids),
        permutation));
  }
}

}  // namespace fuzz
}  // namespace spvtools
