// Copyright (c) 2021 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/opt/convert_to_sampled_image_pass.h"

#include <cctype>
#include <cstring>
#include <tuple>

#include "source/opt/ir_builder.h"
#include "source/util/make_unique.h"
#include "source/util/parse_number.h"

namespace spvtools {
namespace opt {

using VectorOfDescriptorSetAndBindingPairs =
    std::vector<DescriptorSetAndBinding>;
using DescriptorSetBindingToInstruction =
    ConvertToSampledImagePass::DescriptorSetBindingToInstruction;

namespace {

using utils::ParseNumber;

// Returns true if the given char is ':', '\0' or considered as blank space
// (i.e.: '\n', '\r', '\v', '\t', '\f' and ' ').
bool IsSeparator(char ch) {
  return std::strchr(":\0", ch) || std::isspace(ch) != 0;
}

// Reads characters starting from |str| until it meets a separator. Parses a
// number from the characters and stores it into |number|. Returns the pointer
// to the separator if it succeeds. Otherwise, returns nullptr.
const char* ParseNumberUntilSeparator(const char* str, uint32_t* number) {
  const char* number_begin = str;
  while (!IsSeparator(*str)) str++;
  const char* number_end = str;
  std::string number_in_str(number_begin, number_end - number_begin);
  if (!utils::ParseNumber(number_in_str.c_str(), number)) {
    // The descriptor set is not a valid uint32 number.
    return nullptr;
  }
  return str;
}

// Returns id of the image type used for the sampled image type of
// |sampled_image|.
uint32_t GetImageTypeOfSampledImage(analysis::TypeManager* type_mgr,
                                    Instruction* sampled_image) {
  auto* sampled_image_type =
      type_mgr->GetType(sampled_image->type_id())->AsSampledImage();
  return type_mgr->GetTypeInstruction(sampled_image_type->image_type());
}

// Finds the instruction whose id is |inst_id|. Follows the operand of
// OpCopyObject recursively if the opcode of the instruction is OpCopyObject
// and returns the first instruction that does not have OpCopyObject as opcode.
Instruction* GetNonCopyObjectDef(analysis::DefUseManager* def_use_mgr,
                                 uint32_t inst_id) {
  Instruction* inst = def_use_mgr->GetDef(inst_id);
  while (inst->opcode() == spv::Op::OpCopyObject) {
    inst_id = inst->GetSingleWordInOperand(0u);
    inst = def_use_mgr->GetDef(inst_id);
  }
  return inst;
}

}  // namespace

bool ConvertToSampledImagePass::GetDescriptorSetBinding(
    const Instruction& inst,
    DescriptorSetAndBinding* descriptor_set_binding) const {
  auto* decoration_manager = context()->get_decoration_mgr();
  bool found_descriptor_set_to_convert = false;
  bool found_binding_to_convert = false;
  for (auto decorate :
       decoration_manager->GetDecorationsFor(inst.result_id(), false)) {
    spv::Decoration decoration =
        spv::Decoration(decorate->GetSingleWordInOperand(1u));
    if (decoration == spv::Decoration::DescriptorSet) {
      if (found_descriptor_set_to_convert) {
        assert(false && "A resource has two OpDecorate for the descriptor set");
        return false;
      }
      descriptor_set_binding->descriptor_set =
          decorate->GetSingleWordInOperand(2u);
      found_descriptor_set_to_convert = true;
    } else if (decoration == spv::Decoration::Binding) {
      if (found_binding_to_convert) {
        assert(false && "A resource has two OpDecorate for the binding");
        return false;
      }
      descriptor_set_binding->binding = decorate->GetSingleWordInOperand(2u);
      found_binding_to_convert = true;
    }
  }
  return found_descriptor_set_to_convert && found_binding_to_convert;
}

bool ConvertToSampledImagePass::ShouldResourceBeConverted(
    const DescriptorSetAndBinding& descriptor_set_binding) const {
  return descriptor_set_binding_pairs_.find(descriptor_set_binding) !=
         descriptor_set_binding_pairs_.end();
}

const analysis::Type* ConvertToSampledImagePass::GetVariableType(
    const Instruction& variable) const {
  if (variable.opcode() != spv::Op::OpVariable) return nullptr;
  auto* type = context()->get_type_mgr()->GetType(variable.type_id());
  auto* pointer_type = type->AsPointer();
  if (!pointer_type) return nullptr;

  return pointer_type->pointee_type();
}

spv::StorageClass ConvertToSampledImagePass::GetStorageClass(
    const Instruction& variable) const {
  assert(variable.opcode() == spv::Op::OpVariable);
  auto* type = context()->get_type_mgr()->GetType(variable.type_id());
  auto* pointer_type = type->AsPointer();
  if (!pointer_type) return spv::StorageClass::Max;

  return pointer_type->storage_class();
}

bool ConvertToSampledImagePass::CollectResourcesToConvert(
    DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler,
    DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image)
    const {
  for (auto& inst : context()->types_values()) {
    const auto* variable_type = GetVariableType(inst);
    if (variable_type == nullptr) continue;

    DescriptorSetAndBinding descriptor_set_binding;
    if (!GetDescriptorSetBinding(inst, &descriptor_set_binding)) continue;

    if (!ShouldResourceBeConverted(descriptor_set_binding)) {
      continue;
    }

    if (variable_type->AsImage()) {
      if (!descriptor_set_binding_pair_to_image
               ->insert({descriptor_set_binding, &inst})
               .second) {
        return false;
      }
    } else if (variable_type->AsSampler()) {
      if (!descriptor_set_binding_pair_to_sampler
               ->insert({descriptor_set_binding, &inst})
               .second) {
        return false;
      }
    }
  }
  return true;
}

Pass::Status ConvertToSampledImagePass::Process() {
  Status status = Status::SuccessWithoutChange;

  DescriptorSetBindingToInstruction descriptor_set_binding_pair_to_sampler,
      descriptor_set_binding_pair_to_image;
  if (!CollectResourcesToConvert(&descriptor_set_binding_pair_to_sampler,
                                 &descriptor_set_binding_pair_to_image)) {
    return Status::Failure;
  }

  for (auto& image : descriptor_set_binding_pair_to_image) {
    status = CombineStatus(
        status, UpdateImageVariableToSampledImage(image.second, image.first));
    if (status == Status::Failure) {
      return status;
    }
  }

  for (const auto& sampler : descriptor_set_binding_pair_to_sampler) {
    // Converting only a Sampler to Sampled Image is not allowed. It must have a
    // corresponding image to combine the sampler with.
    auto image_itr = descriptor_set_binding_pair_to_image.find(sampler.first);
    if (image_itr == descriptor_set_binding_pair_to_image.end() ||
        image_itr->second == nullptr) {
      return Status::Failure;
    }

    status = CombineStatus(
        status, CheckUsesOfSamplerVariable(sampler.second, image_itr->second));
    if (status == Status::Failure) {
      return status;
    }
  }

  return status;
}

void ConvertToSampledImagePass::FindUses(const Instruction* inst,
                                         std::vector<Instruction*>* uses,
                                         spv::Op user_opcode) const {
  auto* def_use_mgr = context()->get_def_use_mgr();
  def_use_mgr->ForEachUser(inst, [uses, user_opcode, this](Instruction* user) {
    if (user->opcode() == user_opcode) {
      uses->push_back(user);
    } else if (user->opcode() == spv::Op::OpCopyObject) {
      FindUses(user, uses, user_opcode);
    }
  });
}

void ConvertToSampledImagePass::FindUsesOfImage(
    const Instruction* image, std::vector<Instruction*>* uses) const {
  auto* def_use_mgr = context()->get_def_use_mgr();
  def_use_mgr->ForEachUser(image, [uses, this](Instruction* user) {
    switch (user->opcode()) {
      case spv::Op::OpImageFetch:
      case spv::Op::OpImageRead:
      case spv::Op::OpImageWrite:
      case spv::Op::OpImageQueryFormat:
      case spv::Op::OpImageQueryOrder:
      case spv::Op::OpImageQuerySizeLod:
      case spv::Op::OpImageQuerySize:
      case spv::Op::OpImageQueryLevels:
      case spv::Op::OpImageQuerySamples:
      case spv::Op::OpImageSparseFetch:
        uses->push_back(user);
      default:
        break;
    }
    if (user->opcode() == spv::Op::OpCopyObject) {
      FindUsesOfImage(user, uses);
    }
  });
}

Instruction* ConvertToSampledImagePass::CreateImageExtraction(
    Instruction* sampled_image) {
  InstructionBuilder builder(
      context(), sampled_image->NextNode(),
      IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
  return builder.AddUnaryOp(
      GetImageTypeOfSampledImage(context()->get_type_mgr(), sampled_image),
      spv::Op::OpImage, sampled_image->result_id());
}

uint32_t ConvertToSampledImagePass::GetSampledImageTypeForImage(
    Instruction* image_variable) {
  const auto* variable_type = GetVariableType(*image_variable);
  if (variable_type == nullptr) return 0;
  const auto* image_type = variable_type->AsImage();
  if (image_type == nullptr) return 0;

  analysis::Image image_type_for_sampled_image(*image_type);
  analysis::SampledImage sampled_image_type(&image_type_for_sampled_image);
  return context()->get_type_mgr()->GetTypeInstruction(&sampled_image_type);
}

Instruction* ConvertToSampledImagePass::UpdateImageUses(
    Instruction* sampled_image_load) {
  std::vector<Instruction*> uses_of_load;
  FindUsesOfImage(sampled_image_load, &uses_of_load);
  if (uses_of_load.empty()) return nullptr;

  auto* extracted_image = CreateImageExtraction(sampled_image_load);
  for (auto* user : uses_of_load) {
    user->SetInOperand(0, {extracted_image->result_id()});
    context()->get_def_use_mgr()->AnalyzeInstUse(user);
  }
  return extracted_image;
}

bool ConvertToSampledImagePass::
    IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
        Instruction* sampled_image_inst,
        const DescriptorSetAndBinding& descriptor_set_binding) {
  auto* def_use_mgr = context()->get_def_use_mgr();
  uint32_t sampler_id = sampled_image_inst->GetSingleWordInOperand(1u);
  auto* sampler_load = def_use_mgr->GetDef(sampler_id);
  if (sampler_load->opcode() != spv::Op::OpLoad) return false;
  auto* sampler = def_use_mgr->GetDef(sampler_load->GetSingleWordInOperand(0u));
  DescriptorSetAndBinding sampler_descriptor_set_binding;
  return GetDescriptorSetBinding(*sampler, &sampler_descriptor_set_binding) &&
         sampler_descriptor_set_binding == descriptor_set_binding;
}

void ConvertToSampledImagePass::UpdateSampledImageUses(
    Instruction* image_load, Instruction* image_extraction,
    const DescriptorSetAndBinding& image_descriptor_set_binding) {
  std::vector<Instruction*> sampled_image_users;
  FindUses(image_load, &sampled_image_users, spv::Op::OpSampledImage);

  auto* def_use_mgr = context()->get_def_use_mgr();
  for (auto* sampled_image_inst : sampled_image_users) {
    if (IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
            sampled_image_inst, image_descriptor_set_binding)) {
      context()->ReplaceAllUsesWith(sampled_image_inst->result_id(),
                                    image_load->result_id());
      def_use_mgr->AnalyzeInstUse(image_load);
      context()->KillInst(sampled_image_inst);
    } else {
      if (!image_extraction)
        image_extraction = CreateImageExtraction(image_load);
      sampled_image_inst->SetInOperand(0, {image_extraction->result_id()});
      def_use_mgr->AnalyzeInstUse(sampled_image_inst);
    }
  }
}

void ConvertToSampledImagePass::MoveInstructionNextToType(Instruction* inst,
                                                          uint32_t type_id) {
  auto* type_inst = context()->get_def_use_mgr()->GetDef(type_id);
  inst->SetResultType(type_id);
  inst->RemoveFromList();
  inst->InsertAfter(type_inst);
}

bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage(
    Instruction* image_variable, uint32_t sampled_image_type_id) {
  auto* sampled_image_type =
      context()->get_type_mgr()->GetType(sampled_image_type_id);
  if (sampled_image_type == nullptr) return false;
  auto storage_class = GetStorageClass(*image_variable);
  if (storage_class == spv::StorageClass::Max) return false;
  analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class);

  // Make sure |image_variable| is behind its type i.e., avoid the forward
  // reference.
  uint32_t type_id =
      context()->get_type_mgr()->GetTypeInstruction(&sampled_image_pointer);
  MoveInstructionNextToType(image_variable, type_id);
  return true;
}

Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage(
    Instruction* image_variable,
    const DescriptorSetAndBinding& descriptor_set_binding) {
  std::vector<Instruction*> image_variable_loads;
  FindUses(image_variable, &image_variable_loads, spv::Op::OpLoad);
  if (image_variable_loads.empty()) return Status::SuccessWithoutChange;

  const uint32_t sampled_image_type_id =
      GetSampledImageTypeForImage(image_variable);
  if (!sampled_image_type_id) return Status::Failure;

  for (auto* load : image_variable_loads) {
    load->SetResultType(sampled_image_type_id);
    auto* image_extraction = UpdateImageUses(load);
    UpdateSampledImageUses(load, image_extraction, descriptor_set_binding);
  }

  return ConvertImageVariableToSampledImage(image_variable,
                                            sampled_image_type_id)
             ? Status::SuccessWithChange
             : Status::Failure;
}

bool ConvertToSampledImagePass::DoesSampledImageReferenceImage(
    Instruction* sampled_image_inst, Instruction* image_variable) {
  if (sampled_image_inst->opcode() != spv::Op::OpSampledImage) return false;
  auto* def_use_mgr = context()->get_def_use_mgr();
  auto* image_load = GetNonCopyObjectDef(
      def_use_mgr, sampled_image_inst->GetSingleWordInOperand(0u));
  if (image_load->opcode() != spv::Op::OpLoad) return false;
  auto* image =
      GetNonCopyObjectDef(def_use_mgr, image_load->GetSingleWordInOperand(0u));
  return image->opcode() == spv::Op::OpVariable &&
         image->result_id() == image_variable->result_id();
}

Pass::Status ConvertToSampledImagePass::CheckUsesOfSamplerVariable(
    const Instruction* sampler_variable,
    Instruction* image_to_be_combined_with) {
  if (image_to_be_combined_with == nullptr) return Status::Failure;

  std::vector<Instruction*> sampler_variable_loads;
  FindUses(sampler_variable, &sampler_variable_loads, spv::Op::OpLoad);
  for (auto* load : sampler_variable_loads) {
    std::vector<Instruction*> sampled_image_users;
    FindUses(load, &sampled_image_users, spv::Op::OpSampledImage);
    for (auto* sampled_image_inst : sampled_image_users) {
      if (!DoesSampledImageReferenceImage(sampled_image_inst,
                                          image_to_be_combined_with)) {
        return Status::Failure;
      }
    }
  }
  return Status::SuccessWithoutChange;
}

std::unique_ptr<VectorOfDescriptorSetAndBindingPairs>
ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString(
    const char* str) {
  if (!str) return nullptr;

  auto descriptor_set_binding_pairs =
      MakeUnique<VectorOfDescriptorSetAndBindingPairs>();

  while (std::isspace(*str)) str++;  // skip leading spaces.

  // The parsing loop, break when points to the end.
  while (*str) {
    // Parse the descriptor set.
    uint32_t descriptor_set = 0;
    str = ParseNumberUntilSeparator(str, &descriptor_set);
    if (str == nullptr) return nullptr;

    // Find the ':', spaces between the descriptor set and the ':' are not
    // allowed.
    if (*str++ != ':') {
      // ':' not found
      return nullptr;
    }

    // Parse the binding.
    uint32_t binding = 0;
    str = ParseNumberUntilSeparator(str, &binding);
    if (str == nullptr) return nullptr;

    descriptor_set_binding_pairs->push_back({descriptor_set, binding});

    // Skip trailing spaces.
    while (std::isspace(*str)) str++;
  }

  return descriptor_set_binding_pairs;
}

}  // namespace opt
}  // namespace spvtools
