// Copyright (c) 2020 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.

#include "source/fuzz/transformation_equation_instruction.h"

#include "source/fuzz/fuzzer_util.h"
#include "source/fuzz/instruction_descriptor.h"

namespace spvtools {
namespace fuzz {

TransformationEquationInstruction::TransformationEquationInstruction(
    const spvtools::fuzz::protobufs::TransformationEquationInstruction& message)
    : message_(message) {}

TransformationEquationInstruction::TransformationEquationInstruction(
    uint32_t fresh_id, SpvOp opcode, const std::vector<uint32_t>& in_operand_id,
    const protobufs::InstructionDescriptor& instruction_to_insert_before) {
  message_.set_fresh_id(fresh_id);
  message_.set_opcode(opcode);
  for (auto id : in_operand_id) {
    message_.add_in_operand_id(id);
  }
  *message_.mutable_instruction_to_insert_before() =
      instruction_to_insert_before;
}

bool TransformationEquationInstruction::IsApplicable(
    opt::IRContext* ir_context, const TransformationContext& /*unused*/) const {
  // The result id must be fresh.
  if (!fuzzerutil::IsFreshId(ir_context, message_.fresh_id())) {
    return false;
  }

  // The instruction to insert before must exist.
  auto insert_before =
      FindInstruction(message_.instruction_to_insert_before(), ir_context);
  if (!insert_before) {
    return false;
  }
  // The input ids must all exist, not be OpUndef, and be available before this
  // instruction.
  for (auto id : message_.in_operand_id()) {
    auto inst = ir_context->get_def_use_mgr()->GetDef(id);
    if (!inst) {
      return false;
    }
    if (inst->opcode() == SpvOpUndef) {
      return false;
    }
    if (!fuzzerutil::IdIsAvailableBeforeInstruction(ir_context, insert_before,
                                                    id)) {
      return false;
    }
  }

  return MaybeGetResultTypeId(ir_context) != 0;
}

void TransformationEquationInstruction::Apply(
    opt::IRContext* ir_context,
    TransformationContext* transformation_context) const {
  fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());

  opt::Instruction::OperandList in_operands;
  std::vector<uint32_t> rhs_id;
  for (auto id : message_.in_operand_id()) {
    in_operands.push_back({SPV_OPERAND_TYPE_ID, {id}});
    rhs_id.push_back(id);
  }

  FindInstruction(message_.instruction_to_insert_before(), ir_context)
      ->InsertBefore(MakeUnique<opt::Instruction>(
          ir_context, static_cast<SpvOp>(message_.opcode()),
          MaybeGetResultTypeId(ir_context), message_.fresh_id(),
          std::move(in_operands)));

  ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);

  transformation_context->GetFactManager()->AddFactIdEquation(
      message_.fresh_id(), static_cast<SpvOp>(message_.opcode()), rhs_id,
      ir_context);
}

protobufs::Transformation TransformationEquationInstruction::ToMessage() const {
  protobufs::Transformation result;
  *result.mutable_equation_instruction() = message_;
  return result;
}

uint32_t TransformationEquationInstruction::MaybeGetResultTypeId(
    opt::IRContext* ir_context) const {
  auto opcode = static_cast<SpvOp>(message_.opcode());
  switch (opcode) {
    case SpvOpConvertUToF:
    case SpvOpConvertSToF: {
      if (message_.in_operand_id_size() != 1) {
        return 0;
      }

      const auto* type = ir_context->get_type_mgr()->GetType(
          fuzzerutil::GetTypeId(ir_context, message_.in_operand_id(0)));
      if (!type) {
        return 0;
      }

      if (const auto* vector = type->AsVector()) {
        if (!vector->element_type()->AsInteger()) {
          return 0;
        }

        if (auto element_type_id = fuzzerutil::MaybeGetFloatType(
                ir_context, vector->element_type()->AsInteger()->width())) {
          return fuzzerutil::MaybeGetVectorType(ir_context, element_type_id,
                                                vector->element_count());
        }

        return 0;
      } else {
        if (!type->AsInteger()) {
          return 0;
        }

        return fuzzerutil::MaybeGetFloatType(ir_context,
                                             type->AsInteger()->width());
      }
    }
    case SpvOpBitcast: {
      if (message_.in_operand_id_size() != 1) {
        return 0;
      }

      const auto* operand_inst =
          ir_context->get_def_use_mgr()->GetDef(message_.in_operand_id(0));
      if (!operand_inst) {
        return 0;
      }

      const auto* operand_type =
          ir_context->get_type_mgr()->GetType(operand_inst->type_id());
      if (!operand_type) {
        return 0;
      }

      // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3539):
      //  The only constraint on the types of OpBitcast's parameters is that
      //  they must have the same number of bits. Consider improving the code
      //  below to support this in full.
      if (const auto* vector = operand_type->AsVector()) {
        uint32_t component_type_id;
        if (const auto* int_type = vector->element_type()->AsInteger()) {
          component_type_id =
              fuzzerutil::MaybeGetFloatType(ir_context, int_type->width());
        } else if (const auto* float_type = vector->element_type()->AsFloat()) {
          component_type_id = fuzzerutil::MaybeGetIntegerType(
              ir_context, float_type->width(), true);
          if (component_type_id == 0 ||
              fuzzerutil::MaybeGetVectorType(ir_context, component_type_id,
                                             vector->element_count()) == 0) {
            component_type_id = fuzzerutil::MaybeGetIntegerType(
                ir_context, float_type->width(), false);
          }
        } else {
          assert(false && "Only vectors of numerical components are supported");
          return 0;
        }

        if (component_type_id == 0) {
          return 0;
        }

        return fuzzerutil::MaybeGetVectorType(ir_context, component_type_id,
                                              vector->element_count());
      } else if (const auto* int_type = operand_type->AsInteger()) {
        return fuzzerutil::MaybeGetFloatType(ir_context, int_type->width());
      } else if (const auto* float_type = operand_type->AsFloat()) {
        if (auto existing_id = fuzzerutil::MaybeGetIntegerType(
                ir_context, float_type->width(), true)) {
          return existing_id;
        }

        return fuzzerutil::MaybeGetIntegerType(ir_context, float_type->width(),
                                               false);
      } else {
        assert(false &&
               "Operand is not a scalar or a vector of numerical type");
        return 0;
      }
    }
    case SpvOpIAdd:
    case SpvOpISub: {
      if (message_.in_operand_id_size() != 2) {
        return 0;
      }
      uint32_t first_operand_width = 0;
      uint32_t first_operand_type_id = 0;
      for (uint32_t index = 0; index < 2; index++) {
        auto operand_inst = ir_context->get_def_use_mgr()->GetDef(
            message_.in_operand_id(index));
        if (!operand_inst || !operand_inst->type_id()) {
          return 0;
        }
        auto operand_type =
            ir_context->get_type_mgr()->GetType(operand_inst->type_id());
        if (!(operand_type->AsInteger() ||
              (operand_type->AsVector() &&
               operand_type->AsVector()->element_type()->AsInteger()))) {
          return 0;
        }
        uint32_t operand_width =
            operand_type->AsInteger()
                ? 1
                : operand_type->AsVector()->element_count();
        if (index == 0) {
          first_operand_width = operand_width;
          first_operand_type_id = operand_inst->type_id();
        } else {
          assert(first_operand_width != 0 &&
                 "The first operand should have been processed.");
          if (operand_width != first_operand_width) {
            return 0;
          }
        }
      }
      assert(first_operand_type_id != 0 &&
             "A type must have been found for the first operand.");
      return first_operand_type_id;
    }
    case SpvOpLogicalNot: {
      if (message_.in_operand_id().size() != 1) {
        return 0;
      }
      auto operand_inst =
          ir_context->get_def_use_mgr()->GetDef(message_.in_operand_id(0));
      if (!operand_inst || !operand_inst->type_id()) {
        return 0;
      }
      auto operand_type =
          ir_context->get_type_mgr()->GetType(operand_inst->type_id());
      if (!(operand_type->AsBool() ||
            (operand_type->AsVector() &&
             operand_type->AsVector()->element_type()->AsBool()))) {
        return 0;
      }
      return operand_inst->type_id();
    }
    case SpvOpSNegate: {
      if (message_.in_operand_id().size() != 1) {
        return 0;
      }
      auto operand_inst =
          ir_context->get_def_use_mgr()->GetDef(message_.in_operand_id(0));
      if (!operand_inst || !operand_inst->type_id()) {
        return 0;
      }
      auto operand_type =
          ir_context->get_type_mgr()->GetType(operand_inst->type_id());
      if (!(operand_type->AsInteger() ||
            (operand_type->AsVector() &&
             operand_type->AsVector()->element_type()->AsInteger()))) {
        return 0;
      }
      return operand_inst->type_id();
    }
    default:
      assert(false && "Inappropriate opcode for equation instruction.");
      return 0;
  }
}

}  // namespace fuzz
}  // namespace spvtools
