// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// FLUTTER_NOLINT: https://github.com/flutter/flutter/issues/105732

#include "impeller/compiler/reflector.h"

#include <atomic>
#include <optional>
#include <set>
#include <sstream>

#include "flutter/fml/logging.h"
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/compiler/code_gen_template.h"
#include "impeller/compiler/types.h"
#include "impeller/compiler/uniform_sorter.h"
#include "impeller/compiler/utilities.h"
#include "impeller/core/runtime_types.h"
#include "impeller/geometry/half.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"

namespace impeller {
namespace compiler {

static std::string BaseTypeToString(spirv_cross::SPIRType::BaseType type) {
  using Type = spirv_cross::SPIRType::BaseType;
  switch (type) {
    case Type::Void:
      return "ShaderType::kVoid";
    case Type::Boolean:
      return "ShaderType::kBoolean";
    case Type::SByte:
      return "ShaderType::kSignedByte";
    case Type::UByte:
      return "ShaderType::kUnsignedByte";
    case Type::Short:
      return "ShaderType::kSignedShort";
    case Type::UShort:
      return "ShaderType::kUnsignedShort";
    case Type::Int:
      return "ShaderType::kSignedInt";
    case Type::UInt:
      return "ShaderType::kUnsignedInt";
    case Type::Int64:
      return "ShaderType::kSignedInt64";
    case Type::UInt64:
      return "ShaderType::kUnsignedInt64";
    case Type::AtomicCounter:
      return "ShaderType::kAtomicCounter";
    case Type::Half:
      return "ShaderType::kHalfFloat";
    case Type::Float:
      return "ShaderType::kFloat";
    case Type::Double:
      return "ShaderType::kDouble";
    case Type::Struct:
      return "ShaderType::kStruct";
    case Type::Image:
      return "ShaderType::kImage";
    case Type::SampledImage:
      return "ShaderType::kSampledImage";
    case Type::Sampler:
      return "ShaderType::kSampler";
    default:
      return "ShaderType::kUnknown";
  }
}

static std::string ExecutionModelToString(spv::ExecutionModel model) {
  switch (model) {
    case spv::ExecutionModel::ExecutionModelVertex:
      return "vertex";
    case spv::ExecutionModel::ExecutionModelFragment:
      return "fragment";
    case spv::ExecutionModel::ExecutionModelGLCompute:
      return "compute";
    default:
      return "unsupported";
  }
}

static std::string StringToShaderStage(const std::string& str) {
  if (str == "vertex") {
    return "ShaderStage::kVertex";
  }

  if (str == "fragment") {
    return "ShaderStage::kFragment";
  }

  if (str == "compute") {
    return "ShaderStage::kCompute";
  }

  return "ShaderStage::kUnknown";
}

Reflector::Reflector(Options options,
                     const std::shared_ptr<const spirv_cross::ParsedIR>& ir,
                     const std::shared_ptr<fml::Mapping>& shader_data,
                     const CompilerBackend& compiler)
    : options_(std::move(options)),
      ir_(ir),
      shader_data_(shader_data),
      compiler_(compiler) {
  if (!ir_ || !compiler_) {
    return;
  }

  if (auto template_arguments = GenerateTemplateArguments();
      template_arguments.has_value()) {
    template_arguments_ =
        std::make_unique<nlohmann::json>(std::move(template_arguments.value()));
  } else {
    return;
  }

  reflection_header_ = GenerateReflectionHeader();
  if (!reflection_header_) {
    return;
  }

  reflection_cc_ = GenerateReflectionCC();
  if (!reflection_cc_) {
    return;
  }

  runtime_stage_shader_ = GenerateRuntimeStageData();

  is_valid_ = true;
}

Reflector::~Reflector() = default;

bool Reflector::IsValid() const {
  return is_valid_;
}

std::shared_ptr<fml::Mapping> Reflector::GetReflectionJSON() const {
  if (!is_valid_) {
    return nullptr;
  }

  auto json_string =
      std::make_shared<std::string>(template_arguments_->dump(2u));

  return std::make_shared<fml::NonOwnedMapping>(
      reinterpret_cast<const uint8_t*>(json_string->data()),
      json_string->size(), [json_string](auto, auto) {});
}

std::shared_ptr<fml::Mapping> Reflector::GetReflectionHeader() const {
  return reflection_header_;
}

std::shared_ptr<fml::Mapping> Reflector::GetReflectionCC() const {
  return reflection_cc_;
}

std::shared_ptr<RuntimeStageData::Shader> Reflector::GetRuntimeStageShaderData()
    const {
  return runtime_stage_shader_;
}

std::optional<nlohmann::json> Reflector::GenerateTemplateArguments() const {
  nlohmann::json root;

  const auto& entrypoints = compiler_->get_entry_points_and_stages();
  if (entrypoints.size() != 1) {
    VALIDATION_LOG << "Incorrect number of entrypoints in the shader. Found "
                   << entrypoints.size() << " but expected 1.";
    return std::nullopt;
  }

  auto execution_model = entrypoints.front().execution_model;
  {
    root["entrypoint"] = options_.entry_point_name;
    root["shader_name"] = options_.shader_name;
    root["shader_stage"] = ExecutionModelToString(execution_model);
    root["header_file_name"] = options_.header_file_name;
  }

  const auto shader_resources = compiler_->get_shader_resources();

  // Subpass Inputs.
  {
    auto& subpass_inputs = root["subpass_inputs"] = nlohmann::json::array_t{};
    if (auto subpass_inputs_json =
            ReflectResources(shader_resources.subpass_inputs);
        subpass_inputs_json.has_value()) {
      for (auto subpass_input : subpass_inputs_json.value()) {
        subpass_input["descriptor_type"] = "DescriptorType::kInputAttachment";
        subpass_inputs.emplace_back(std::move(subpass_input));
      }
    } else {
      return std::nullopt;
    }
  }

  // Uniform and storage buffers.
  {
    auto& buffers = root["buffers"] = nlohmann::json::array_t{};
    if (auto uniform_buffers_json =
            ReflectResources(shader_resources.uniform_buffers);
        uniform_buffers_json.has_value()) {
      for (auto uniform_buffer : uniform_buffers_json.value()) {
        uniform_buffer["descriptor_type"] = "DescriptorType::kUniformBuffer";
        buffers.emplace_back(std::move(uniform_buffer));
      }
    } else {
      return std::nullopt;
    }
    if (auto storage_buffers_json =
            ReflectResources(shader_resources.storage_buffers);
        storage_buffers_json.has_value()) {
      for (auto uniform_buffer : storage_buffers_json.value()) {
        uniform_buffer["descriptor_type"] = "DescriptorType::kStorageBuffer";
        buffers.emplace_back(std::move(uniform_buffer));
      }
    } else {
      return std::nullopt;
    }
  }

  {
    auto& stage_inputs = root["stage_inputs"] = nlohmann::json::array_t{};
    if (auto stage_inputs_json = ReflectResources(
            shader_resources.stage_inputs,
            /*compute_offsets=*/execution_model == spv::ExecutionModelVertex);
        stage_inputs_json.has_value()) {
      stage_inputs = std::move(stage_inputs_json.value());
    } else {
      return std::nullopt;
    }
  }

  {
    auto combined_sampled_images =
        ReflectResources(shader_resources.sampled_images);
    auto images = ReflectResources(shader_resources.separate_images);
    auto samplers = ReflectResources(shader_resources.separate_samplers);
    if (!combined_sampled_images.has_value() || !images.has_value() ||
        !samplers.has_value()) {
      return std::nullopt;
    }
    auto& sampled_images = root["sampled_images"] = nlohmann::json::array_t{};
    for (auto value : combined_sampled_images.value()) {
      value["descriptor_type"] = "DescriptorType::kSampledImage";
      sampled_images.emplace_back(std::move(value));
    }
    for (auto value : images.value()) {
      value["descriptor_type"] = "DescriptorType::kImage";
      sampled_images.emplace_back(std::move(value));
    }
    for (auto value : samplers.value()) {
      value["descriptor_type"] = "DescriptorType::kSampledSampler";
      sampled_images.emplace_back(std::move(value));
    }
  }

  if (auto stage_outputs = ReflectResources(shader_resources.stage_outputs);
      stage_outputs.has_value()) {
    root["stage_outputs"] = std::move(stage_outputs.value());
  } else {
    return std::nullopt;
  }

  {
    auto& struct_definitions = root["struct_definitions"] =
        nlohmann::json::array_t{};
    if (entrypoints.front().execution_model ==
            spv::ExecutionModel::ExecutionModelVertex &&
        !shader_resources.stage_inputs.empty()) {
      if (auto struc =
              ReflectPerVertexStructDefinition(shader_resources.stage_inputs);
          struc.has_value()) {
        struct_definitions.emplace_back(EmitStructDefinition(struc.value()));
      } else {
        // If there are stage inputs, it is an error to not generate a per
        // vertex data struct for a vertex like shader stage.
        return std::nullopt;
      }
    }

    std::set<spirv_cross::ID> known_structs;
    ir_->for_each_typed_id<spirv_cross::SPIRType>(
        [&](uint32_t, const spirv_cross::SPIRType& type) {
          if (known_structs.find(type.self) != known_structs.end()) {
            // Iterating over types this way leads to duplicates which may cause
            // duplicate struct definitions.
            return;
          }
          known_structs.insert(type.self);
          if (auto struc = ReflectStructDefinition(type.self);
              struc.has_value()) {
            struct_definitions.emplace_back(
                EmitStructDefinition(struc.value()));
          }
        });
  }

  root["bind_prototypes"] =
      EmitBindPrototypes(shader_resources, execution_model);

  return root;
}

std::shared_ptr<fml::Mapping> Reflector::GenerateReflectionHeader() const {
  return InflateTemplate(kReflectionHeaderTemplate);
}

std::shared_ptr<fml::Mapping> Reflector::GenerateReflectionCC() const {
  return InflateTemplate(kReflectionCCTemplate);
}

static std::optional<RuntimeStageBackend> GetRuntimeStageBackend(
    TargetPlatform target_platform) {
  switch (target_platform) {
    case TargetPlatform::kUnknown:
    case TargetPlatform::kMetalDesktop:
    case TargetPlatform::kMetalIOS:
    case TargetPlatform::kOpenGLES:
    case TargetPlatform::kOpenGLDesktop:
    case TargetPlatform::kVulkan:
      return std::nullopt;
    case TargetPlatform::kRuntimeStageMetal:
      return RuntimeStageBackend::kMetal;
    case TargetPlatform::kRuntimeStageGLES:
      return RuntimeStageBackend::kOpenGLES;
    case TargetPlatform::kRuntimeStageVulkan:
      return RuntimeStageBackend::kVulkan;
    case TargetPlatform::kSkSL:
      return RuntimeStageBackend::kSkSL;
  }
  FML_UNREACHABLE();
}

std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
    const {
  auto backend = GetRuntimeStageBackend(options_.target_platform);
  if (!backend.has_value()) {
    return nullptr;
  }

  const auto& entrypoints = compiler_->get_entry_points_and_stages();
  if (entrypoints.size() != 1u) {
    VALIDATION_LOG << "Single entrypoint not found.";
    return nullptr;
  }
  auto data = std::make_unique<RuntimeStageData::Shader>();
  data->entrypoint = options_.entry_point_name;
  data->stage = entrypoints.front().execution_model;
  data->shader = shader_data_;
  data->backend = backend.value();

  // Sort the IR so that the uniforms are in declaration order.
  std::vector<spirv_cross::ID> uniforms =
      SortUniforms(ir_.get(), compiler_.GetCompiler());

  for (auto& sorted_id : uniforms) {
    auto var = ir_->ids[sorted_id].get<spirv_cross::SPIRVariable>();
    const auto spir_type = compiler_->get_type(var.basetype);
    UniformDescription uniform_description;
    uniform_description.name = compiler_->get_name(var.self);
    uniform_description.location = compiler_->get_decoration(
        var.self, spv::Decoration::DecorationLocation);
    uniform_description.type = spir_type.basetype;
    uniform_description.rows = spir_type.vecsize;
    uniform_description.columns = spir_type.columns;
    uniform_description.bit_width = spir_type.width;
    uniform_description.array_elements = GetArrayElements(spir_type);
    data->uniforms.emplace_back(std::move(uniform_description));
  }

  // We only need to worry about storing vertex attributes.
  if (entrypoints.front().execution_model == spv::ExecutionModelVertex) {
    const auto inputs = compiler_->get_shader_resources().stage_inputs;
    auto input_offsets = ComputeOffsets(inputs);
    for (const auto& input : inputs) {
      auto location = compiler_->get_decoration(
          input.id, spv::Decoration::DecorationLocation);
      std::optional<size_t> offset = input_offsets[location];

      const auto type = compiler_->get_type(input.type_id);

      InputDescription input_description;
      input_description.name = input.name;
      input_description.location = compiler_->get_decoration(
          input.id, spv::Decoration::DecorationLocation);
      input_description.set = compiler_->get_decoration(
          input.id, spv::Decoration::DecorationDescriptorSet);
      input_description.binding = compiler_->get_decoration(
          input.id, spv::Decoration::DecorationBinding);
      input_description.type = type.basetype;
      input_description.bit_width = type.width;
      input_description.vec_size = type.vecsize;
      input_description.columns = type.columns;
      input_description.offset = offset.value_or(0u);
      data->inputs.emplace_back(std::move(input_description));
    }
  }

  return data;
}

std::optional<uint32_t> Reflector::GetArrayElements(
    const spirv_cross::SPIRType& type) const {
  if (type.array.empty()) {
    return std::nullopt;
  }
  FML_CHECK(type.array.size() == 1)
      << "Multi-dimensional arrays are not supported.";
  FML_CHECK(type.array_size_literal.front())
      << "Must use a literal for array sizes.";
  return type.array.front();
}

static std::string ToString(CompilerBackend::Type type) {
  switch (type) {
    case CompilerBackend::Type::kMSL:
      return "Metal Shading Language";
    case CompilerBackend::Type::kGLSL:
      return "OpenGL Shading Language";
    case CompilerBackend::Type::kSkSL:
      return "SkSL Shading Language";
  }
  FML_UNREACHABLE();
}

std::shared_ptr<fml::Mapping> Reflector::InflateTemplate(
    std::string_view tmpl) const {
  inja::Environment env;
  env.set_trim_blocks(true);
  env.set_lstrip_blocks(true);

  env.add_callback("camel_case", 1u, [](inja::Arguments& args) {
    return ToCamelCase(args.at(0u)->get<std::string>());
  });

  env.add_callback("to_shader_stage", 1u, [](inja::Arguments& args) {
    return StringToShaderStage(args.at(0u)->get<std::string>());
  });

  env.add_callback("get_generator_name", 0u,
                   [type = compiler_.GetType()](inja::Arguments& args) {
                     return ToString(type);
                   });

  auto inflated_template =
      std::make_shared<std::string>(env.render(tmpl, *template_arguments_));

  return std::make_shared<fml::NonOwnedMapping>(
      reinterpret_cast<const uint8_t*>(inflated_template->data()),
      inflated_template->size(), [inflated_template](auto, auto) {});
}

std::vector<size_t> Reflector::ComputeOffsets(
    const spirv_cross::SmallVector<spirv_cross::Resource>& resources) const {
  std::vector<size_t> offsets(resources.size(), 0);
  if (resources.size() == 0) {
    return offsets;
  }
  for (const auto& resource : resources) {
    const auto type = compiler_->get_type(resource.type_id);
    auto location = compiler_->get_decoration(
        resource.id, spv::Decoration::DecorationLocation);
    // Malformed shader, will be caught later on.
    if (location >= resources.size() || location < 0) {
      location = 0;
    }
    offsets[location] = (type.width * type.vecsize) / 8;
  }
  for (size_t i = 1; i < resources.size(); i++) {
    offsets[i] += offsets[i - 1];
  }
  for (size_t i = resources.size() - 1; i > 0; i--) {
    offsets[i] = offsets[i - 1];
  }
  offsets[0] = 0;

  return offsets;
}

std::optional<nlohmann::json::object_t> Reflector::ReflectResource(
    const spirv_cross::Resource& resource,
    std::optional<size_t> offset) const {
  nlohmann::json::object_t result;

  result["name"] = resource.name;
  result["descriptor_set"] = compiler_->get_decoration(
      resource.id, spv::Decoration::DecorationDescriptorSet);
  result["binding"] = compiler_->get_decoration(
      resource.id, spv::Decoration::DecorationBinding);
  result["set"] = compiler_->get_decoration(
      resource.id, spv::Decoration::DecorationDescriptorSet);
  result["location"] = compiler_->get_decoration(
      resource.id, spv::Decoration::DecorationLocation);
  result["index"] =
      compiler_->get_decoration(resource.id, spv::Decoration::DecorationIndex);
  result["ext_res_0"] = compiler_.GetExtendedMSLResourceBinding(
      CompilerBackend::ExtendedResourceIndex::kPrimary, resource.id);
  result["ext_res_1"] = compiler_.GetExtendedMSLResourceBinding(
      CompilerBackend::ExtendedResourceIndex::kSecondary, resource.id);
  auto type = ReflectType(resource.type_id);
  if (!type.has_value()) {
    return std::nullopt;
  }
  result["type"] = std::move(type.value());
  result["offset"] = offset.value_or(0u);
  return result;
}

std::optional<nlohmann::json::object_t> Reflector::ReflectType(
    const spirv_cross::TypeID& type_id) const {
  nlohmann::json::object_t result;

  const auto type = compiler_->get_type(type_id);

  result["type_name"] = BaseTypeToString(type.basetype);
  result["bit_width"] = type.width;
  result["vec_size"] = type.vecsize;
  result["columns"] = type.columns;
  auto& members = result["members"] = nlohmann::json::array_t{};
  if (type.basetype == spirv_cross::SPIRType::BaseType::Struct) {
    for (const auto& struct_member : ReadStructMembers(type_id)) {
      auto member = nlohmann::json::object_t{};
      member["name"] = struct_member.name;
      member["type"] = struct_member.type;
      member["base_type"] = struct_member.base_type;
      member["offset"] = struct_member.offset;
      member["size"] = struct_member.size;
      member["byte_length"] = struct_member.byte_length;
      if (struct_member.array_elements.has_value()) {
        member["array_elements"] = struct_member.array_elements.value();
      } else {
        member["array_elements"] = "std::nullopt";
      }
      members.emplace_back(std::move(member));
    }
  }

  return result;
}

std::optional<nlohmann::json::array_t> Reflector::ReflectResources(
    const spirv_cross::SmallVector<spirv_cross::Resource>& resources,
    bool compute_offsets) const {
  nlohmann::json::array_t result;
  result.reserve(resources.size());
  std::vector<size_t> offsets;
  if (compute_offsets) {
    offsets = ComputeOffsets(resources);
  }
  for (const auto& resource : resources) {
    std::optional<size_t> maybe_offset = std::nullopt;
    if (compute_offsets) {
      auto location = compiler_->get_decoration(
          resource.id, spv::Decoration::DecorationLocation);
      maybe_offset = offsets[location];
    }
    if (auto reflected = ReflectResource(resource, maybe_offset);
        reflected.has_value()) {
      result.emplace_back(std::move(reflected.value()));
    } else {
      return std::nullopt;
    }
  }
  return result;
}

static std::string TypeNameWithPaddingOfSize(size_t size) {
  std::stringstream stream;
  stream << "Padding<" << size << ">";
  return stream.str();
}

struct KnownType {
  std::string name;
  size_t byte_size = 0;
};

static std::optional<KnownType> ReadKnownScalarType(
    spirv_cross::SPIRType::BaseType type) {
  switch (type) {
    case spirv_cross::SPIRType::BaseType::Boolean:
      return KnownType{
          .name = "bool",
          .byte_size = sizeof(bool),
      };
    case spirv_cross::SPIRType::BaseType::Float:
      return KnownType{
          .name = "Scalar",
          .byte_size = sizeof(Scalar),
      };
    case spirv_cross::SPIRType::BaseType::Half:
      return KnownType{
          .name = "Half",
          .byte_size = sizeof(Half),
      };
    case spirv_cross::SPIRType::BaseType::UInt:
      return KnownType{
          .name = "uint32_t",
          .byte_size = sizeof(uint32_t),
      };
    case spirv_cross::SPIRType::BaseType::Int:
      return KnownType{
          .name = "int32_t",
          .byte_size = sizeof(int32_t),
      };
    default:
      break;
  }
  return std::nullopt;
}

//------------------------------------------------------------------------------
/// @brief      Get the reflected struct size. In the vast majority of the
///             cases, this is the same as the declared struct size as given by
///             the compiler. But, additional padding may need to be introduced
///             after the end of the struct to keep in line with the alignment
///             requirement of the individual struct members. This method
///             figures out the actual size of the reflected struct that can be
///             referenced in native code.
///
/// @param[in]  members  The members
///
/// @return     The reflected structure size.
///
static size_t GetReflectedStructSize(const std::vector<StructMember>& members) {
  auto struct_size = 0u;
  for (const auto& member : members) {
    struct_size += member.byte_length;
  }
  return struct_size;
}

std::vector<StructMember> Reflector::ReadStructMembers(
    const spirv_cross::TypeID& type_id) const {
  const auto& struct_type = compiler_->get_type(type_id);
  FML_CHECK(struct_type.basetype == spirv_cross::SPIRType::BaseType::Struct);

  std::vector<StructMember> result;

  size_t current_byte_offset = 0;
  size_t max_member_alignment = 0;

  for (size_t i = 0; i < struct_type.member_types.size(); i++) {
    const auto& member = compiler_->get_type(struct_type.member_types[i]);
    const auto struct_member_offset =
        compiler_->type_struct_member_offset(struct_type, i);
    auto array_elements = GetArrayElements(member);

    if (struct_member_offset > current_byte_offset) {
      const auto alignment_pad = struct_member_offset - current_byte_offset;
      result.emplace_back(StructMember{
          TypeNameWithPaddingOfSize(alignment_pad),                 // type
          BaseTypeToString(spirv_cross::SPIRType::BaseType::Void),  // basetype
          SPrintF("_PADDING_%s_",
                  GetMemberNameAtIndex(struct_type, i).c_str()),  // name
          current_byte_offset,                                    // offset
          alignment_pad,                                          // size
          alignment_pad,                                          // byte_length
          std::nullopt,  // array_elements
          0,             // element_padding
      });
      current_byte_offset += alignment_pad;
    }

    max_member_alignment =
        std::max<size_t>(max_member_alignment,
                         (member.width / 8) * member.columns * member.vecsize);

    FML_CHECK(current_byte_offset == struct_member_offset);

    // A user defined struct.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Struct) {
      const size_t size =
          GetReflectedStructSize(ReadStructMembers(member.self));
      uint32_t stride = GetArrayStride<0>(struct_type, member, i);
      if (stride == 0) {
        stride = size;
      }
      uint32_t element_padding = stride - size;
      result.emplace_back(StructMember{
          compiler_->get_name(member.self),      // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          size,                                  // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed 4x4 Matrix is special cased as we know how to work with
    // those.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Float &&  //
        member.width == sizeof(Scalar) * 8 &&                         //
        member.columns == 4 &&                                        //
        member.vecsize == 4                                           //
    ) {
      uint32_t stride = GetArrayStride<sizeof(Matrix)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(Matrix);
      result.emplace_back(StructMember{
          "Matrix",                              // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(Matrix),                        // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed UintPoint32 (uvec2)
    if (member.basetype == spirv_cross::SPIRType::BaseType::UInt &&  //
        member.width == sizeof(uint32_t) * 8 &&                      //
        member.columns == 1 &&                                       //
        member.vecsize == 2                                          //
    ) {
      uint32_t stride =
          GetArrayStride<sizeof(UintPoint32)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(UintPoint32);
      result.emplace_back(StructMember{
          "UintPoint32",                         // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(UintPoint32),                   // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed UintPoint32 (ivec2)
    if (member.basetype == spirv_cross::SPIRType::BaseType::Int &&  //
        member.width == sizeof(int32_t) * 8 &&                      //
        member.columns == 1 &&                                      //
        member.vecsize == 2                                         //
    ) {
      uint32_t stride =
          GetArrayStride<sizeof(IPoint32)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(IPoint32);
      result.emplace_back(StructMember{
          "IPoint32",                            // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(IPoint32),                      // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed Point (vec2).
    if (member.basetype == spirv_cross::SPIRType::BaseType::Float &&  //
        member.width == sizeof(float) * 8 &&                          //
        member.columns == 1 &&                                        //
        member.vecsize == 2                                           //
    ) {
      uint32_t stride = GetArrayStride<sizeof(Point)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(Point);
      result.emplace_back(StructMember{
          "Point",                               // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(Point),                         // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed Vector3.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Float &&  //
        member.width == sizeof(float) * 8 &&                          //
        member.columns == 1 &&                                        //
        member.vecsize == 3                                           //
    ) {
      uint32_t stride = GetArrayStride<sizeof(Vector3)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(Vector3);
      result.emplace_back(StructMember{
          "Vector3",                             // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(Vector3),                       // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed Vector4.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Float &&  //
        member.width == sizeof(float) * 8 &&                          //
        member.columns == 1 &&                                        //
        member.vecsize == 4                                           //
    ) {
      uint32_t stride = GetArrayStride<sizeof(Vector4)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(Vector4);
      result.emplace_back(StructMember{
          "Vector4",                             // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(Vector4),                       // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed half Point (vec2).
    if (member.basetype == spirv_cross::SPIRType::BaseType::Half &&  //
        member.width == sizeof(Half) * 8 &&                          //
        member.columns == 1 &&                                       //
        member.vecsize == 2                                          //
    ) {
      uint32_t stride =
          GetArrayStride<sizeof(HalfVector2)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(HalfVector2);
      result.emplace_back(StructMember{
          "HalfVector2",                         // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(HalfVector2),                   // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed Half Float Vector3.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Half &&  //
        member.width == sizeof(Half) * 8 &&                          //
        member.columns == 1 &&                                       //
        member.vecsize == 3                                          //
    ) {
      uint32_t stride =
          GetArrayStride<sizeof(HalfVector3)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(HalfVector3);
      result.emplace_back(StructMember{
          "HalfVector3",                         // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(HalfVector3),                   // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Tightly packed Half Float Vector4.
    if (member.basetype == spirv_cross::SPIRType::BaseType::Half &&  //
        member.width == sizeof(Half) * 8 &&                          //
        member.columns == 1 &&                                       //
        member.vecsize == 4                                          //
    ) {
      uint32_t stride =
          GetArrayStride<sizeof(HalfVector4)>(struct_type, member, i);
      uint32_t element_padding = stride - sizeof(HalfVector4);
      result.emplace_back(StructMember{
          "HalfVector4",                         // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          sizeof(HalfVector4),                   // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }

    // Other isolated scalars (like bool, int, float/Scalar, etc..).
    {
      auto maybe_known_type = ReadKnownScalarType(member.basetype);
      if (maybe_known_type.has_value() &&  //
          member.columns == 1 &&           //
          member.vecsize == 1              //
      ) {
        uint32_t stride = GetArrayStride<0>(struct_type, member, i);
        if (stride == 0) {
          stride = maybe_known_type.value().byte_size;
        }
        uint32_t element_padding = stride - maybe_known_type.value().byte_size;
        // Add the type directly.
        result.emplace_back(StructMember{
            maybe_known_type.value().name,         // type
            BaseTypeToString(member.basetype),     // basetype
            GetMemberNameAtIndex(struct_type, i),  // name
            struct_member_offset,                  // offset
            maybe_known_type.value().byte_size,    // size
            stride * array_elements.value_or(1),   // byte_length
            array_elements,                        // array_elements
            element_padding,                       // element_padding
        });
        current_byte_offset += stride * array_elements.value_or(1);
        continue;
      }
    }

    // Catch all for unknown types. Just add the necessary padding to the struct
    // and move on.
    {
      const size_t size = (member.width * member.columns * member.vecsize) / 8u;
      uint32_t stride = GetArrayStride<0>(struct_type, member, i);
      if (stride == 0) {
        stride = size;
      }
      auto element_padding = stride - size;
      result.emplace_back(StructMember{
          TypeNameWithPaddingOfSize(size),       // type
          BaseTypeToString(member.basetype),     // basetype
          GetMemberNameAtIndex(struct_type, i),  // name
          struct_member_offset,                  // offset
          size,                                  // size
          stride * array_elements.value_or(1),   // byte_length
          array_elements,                        // array_elements
          element_padding,                       // element_padding
      });
      current_byte_offset += stride * array_elements.value_or(1);
      continue;
    }
  }

  if (max_member_alignment > 0u) {
    const auto struct_length = current_byte_offset;
    {
      const auto excess = struct_length % max_member_alignment;
      if (excess != 0) {
        const auto padding = max_member_alignment - excess;
        result.emplace_back(StructMember{
            TypeNameWithPaddingOfSize(padding),  // type
            BaseTypeToString(
                spirv_cross::SPIRType::BaseType::Void),  // basetype
            "_PADDING_",                                 // name
            current_byte_offset,                         // offset
            padding,                                     // size
            padding,                                     // byte_length
            std::nullopt,                                // array_elements
            0,                                           // element_padding
        });
      }
    }
  }

  return result;
}

std::optional<Reflector::StructDefinition> Reflector::ReflectStructDefinition(
    const spirv_cross::TypeID& type_id) const {
  const auto& type = compiler_->get_type(type_id);
  if (type.basetype != spirv_cross::SPIRType::BaseType::Struct) {
    return std::nullopt;
  }

  const auto struct_name = compiler_->get_name(type_id);
  if (struct_name.find("_RESERVED_IDENTIFIER_") != std::string::npos) {
    return std::nullopt;
  }

  auto struct_members = ReadStructMembers(type_id);
  auto reflected_struct_size = GetReflectedStructSize(struct_members);

  StructDefinition struc;
  struc.name = struct_name;
  struc.byte_length = reflected_struct_size;
  struc.members = std::move(struct_members);
  return struc;
}

nlohmann::json::object_t Reflector::EmitStructDefinition(
    std::optional<Reflector::StructDefinition> struc) const {
  nlohmann::json::object_t result;
  result["name"] = struc->name;
  result["byte_length"] = struc->byte_length;
  auto& members = result["members"] = nlohmann::json::array_t{};
  for (const auto& struct_member : struc->members) {
    auto& member = members.emplace_back(nlohmann::json::object_t{});
    member["name"] = struct_member.name;
    member["type"] = struct_member.type;
    member["base_type"] = struct_member.base_type;
    member["offset"] = struct_member.offset;
    member["byte_length"] = struct_member.byte_length;
    if (struct_member.array_elements.has_value()) {
      member["array_elements"] = struct_member.array_elements.value();
    } else {
      member["array_elements"] = "std::nullopt";
    }
    member["element_padding"] = struct_member.element_padding;
  }
  return result;
}

struct VertexType {
  std::string type_name;
  std::string base_type_name;
  std::string variable_name;
  size_t byte_length = 0u;
};

static VertexType VertexTypeFromInputResource(
    const spirv_cross::Compiler& compiler,
    const spirv_cross::Resource* resource) {
  VertexType result;
  result.variable_name = resource->name;
  const auto type = compiler.get_type(resource->type_id);
  result.base_type_name = BaseTypeToString(type.basetype);
  const auto total_size = type.columns * type.vecsize * type.width / 8u;
  result.byte_length = total_size;

  if (type.basetype == spirv_cross::SPIRType::BaseType::Float &&
      type.columns == 1u && type.vecsize == 2u &&
      type.width == sizeof(float) * 8u) {
    result.type_name = "Point";
  } else if (type.basetype == spirv_cross::SPIRType::BaseType::Float &&
             type.columns == 1u && type.vecsize == 4u &&
             type.width == sizeof(float) * 8u) {
    result.type_name = "Vector4";
  } else if (type.basetype == spirv_cross::SPIRType::BaseType::Float &&
             type.columns == 1u && type.vecsize == 3u &&
             type.width == sizeof(float) * 8u) {
    result.type_name = "Vector3";
  } else if (type.basetype == spirv_cross::SPIRType::BaseType::Float &&
             type.columns == 1u && type.vecsize == 1u &&
             type.width == sizeof(float) * 8u) {
    result.type_name = "Scalar";
  } else if (type.basetype == spirv_cross::SPIRType::BaseType::Int &&
             type.columns == 1u && type.vecsize == 1u &&
             type.width == sizeof(int32_t) * 8u) {
    result.type_name = "int32_t";
  } else {
    // Catch all unknown padding.
    result.type_name = TypeNameWithPaddingOfSize(total_size);
  }

  return result;
}

std::optional<Reflector::StructDefinition>
Reflector::ReflectPerVertexStructDefinition(
    const spirv_cross::SmallVector<spirv_cross::Resource>& stage_inputs) const {
  // Avoid emitting a zero sized structure. The code gen templates assume a
  // non-zero size.
  if (stage_inputs.empty()) {
    return std::nullopt;
  }

  // Validate locations are contiguous and there are no duplicates.
  std::set<uint32_t> locations;
  for (const auto& input : stage_inputs) {
    auto location = compiler_->get_decoration(
        input.id, spv::Decoration::DecorationLocation);
    if (locations.count(location) != 0) {
      // Duplicate location. Bail.
      return std::nullopt;
    }
    locations.insert(location);
  }

  for (size_t i = 0; i < locations.size(); i++) {
    if (locations.count(i) != 1) {
      // Locations are not contiguous. This usually happens when a single stage
      // input takes multiple input slots. No reflection information can be
      // generated for such cases anyway. So bail! It is up to the shader author
      // to make sure one stage input maps to a single input slot.
      return std::nullopt;
    }
  }

  auto input_for_location =
      [&](uint32_t queried_location) -> const spirv_cross::Resource* {
    for (const auto& input : stage_inputs) {
      auto location = compiler_->get_decoration(
          input.id, spv::Decoration::DecorationLocation);
      if (location == queried_location) {
        return &input;
      }
    }
    // This really cannot happen with all the validation above.
    FML_UNREACHABLE();
    return nullptr;
  };

  StructDefinition struc;
  struc.name = "PerVertexData";
  struc.byte_length = 0u;
  for (size_t i = 0; i < locations.size(); i++) {
    auto resource = input_for_location(i);
    if (resource == nullptr) {
      return std::nullopt;
    }
    const auto vertex_type =
        VertexTypeFromInputResource(*compiler_.GetCompiler(), resource);

    auto member = StructMember{
        vertex_type.type_name,       // type
        vertex_type.base_type_name,  // base type
        vertex_type.variable_name,   // name
        struc.byte_length,           // offset
        vertex_type.byte_length,     // size
        vertex_type.byte_length,     // byte_length
        std::nullopt,                // array_elements
        0,                           // element_padding
    };
    struc.byte_length += vertex_type.byte_length;
    struc.members.emplace_back(std::move(member));
  }
  return struc;
}

std::optional<std::string> Reflector::GetMemberNameAtIndexIfExists(
    const spirv_cross::SPIRType& parent_type,
    size_t index) const {
  if (parent_type.type_alias != 0) {
    return GetMemberNameAtIndexIfExists(
        compiler_->get_type(parent_type.type_alias), index);
  }

  if (auto found = ir_->meta.find(parent_type.self); found != ir_->meta.end()) {
    const auto& members = found->second.members;
    if (index < members.size() && !members[index].alias.empty()) {
      return members[index].alias;
    }
  }
  return std::nullopt;
}

std::string Reflector::GetMemberNameAtIndex(
    const spirv_cross::SPIRType& parent_type,
    size_t index,
    std::string suffix) const {
  if (auto name = GetMemberNameAtIndexIfExists(parent_type, index);
      name.has_value()) {
    return name.value();
  }
  static std::atomic_size_t sUnnamedMembersID;
  std::stringstream stream;
  stream << "unnamed_" << sUnnamedMembersID++ << suffix;
  return stream.str();
}

std::vector<Reflector::BindPrototype> Reflector::ReflectBindPrototypes(
    const spirv_cross::ShaderResources& resources,
    spv::ExecutionModel execution_model) const {
  std::vector<BindPrototype> prototypes;
  for (const auto& uniform_buffer : resources.uniform_buffers) {
    auto& proto = prototypes.emplace_back(BindPrototype{});
    proto.return_type = "bool";
    proto.name = ToCamelCase(uniform_buffer.name);
    {
      std::stringstream stream;
      stream << "Bind uniform buffer for resource named " << uniform_buffer.name
             << ".";
      proto.docstring = stream.str();
    }
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "ResourceBinder&",
        .argument_name = "command",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "BufferView",
        .argument_name = "view",
    });
  }
  for (const auto& storage_buffer : resources.storage_buffers) {
    auto& proto = prototypes.emplace_back(BindPrototype{});
    proto.return_type = "bool";
    proto.name = ToCamelCase(storage_buffer.name);
    {
      std::stringstream stream;
      stream << "Bind storage buffer for resource named " << storage_buffer.name
             << ".";
      proto.docstring = stream.str();
    }
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "ResourceBinder&",
        .argument_name = "command",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "BufferView",
        .argument_name = "view",
    });
  }
  for (const auto& sampled_image : resources.sampled_images) {
    auto& proto = prototypes.emplace_back(BindPrototype{});
    proto.return_type = "bool";
    proto.name = ToCamelCase(sampled_image.name);
    {
      std::stringstream stream;
      stream << "Bind combined image sampler for resource named "
             << sampled_image.name << ".";
      proto.docstring = stream.str();
    }
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "ResourceBinder&",
        .argument_name = "command",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "std::shared_ptr<const Texture>",
        .argument_name = "texture",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "std::shared_ptr<const Sampler>",
        .argument_name = "sampler",
    });
  }
  for (const auto& separate_image : resources.separate_images) {
    auto& proto = prototypes.emplace_back(BindPrototype{});
    proto.return_type = "bool";
    proto.name = ToCamelCase(separate_image.name);
    {
      std::stringstream stream;
      stream << "Bind separate image for resource named " << separate_image.name
             << ".";
      proto.docstring = stream.str();
    }
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "Command&",
        .argument_name = "command",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "std::shared_ptr<const Texture>",
        .argument_name = "texture",
    });
  }
  for (const auto& separate_sampler : resources.separate_samplers) {
    auto& proto = prototypes.emplace_back(BindPrototype{});
    proto.return_type = "bool";
    proto.name = ToCamelCase(separate_sampler.name);
    {
      std::stringstream stream;
      stream << "Bind separate sampler for resource named "
             << separate_sampler.name << ".";
      proto.docstring = stream.str();
    }
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "Command&",
        .argument_name = "command",
    });
    proto.args.push_back(BindPrototypeArgument{
        .type_name = "std::shared_ptr<const Sampler>",
        .argument_name = "sampler",
    });
  }
  return prototypes;
}

nlohmann::json::array_t Reflector::EmitBindPrototypes(
    const spirv_cross::ShaderResources& resources,
    spv::ExecutionModel execution_model) const {
  const auto prototypes = ReflectBindPrototypes(resources, execution_model);
  nlohmann::json::array_t result;
  for (const auto& res : prototypes) {
    auto& item = result.emplace_back(nlohmann::json::object_t{});
    item["return_type"] = res.return_type;
    item["name"] = res.name;
    item["docstring"] = res.docstring;
    auto& args = item["args"] = nlohmann::json::array_t{};
    for (const auto& arg : res.args) {
      auto& json_arg = args.emplace_back(nlohmann::json::object_t{});
      json_arg["type_name"] = arg.type_name;
      json_arg["argument_name"] = arg.argument_name;
    }
  }
  return result;
}

}  // namespace compiler
}  // namespace impeller
