// 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.

#include "impeller/renderer/backend/vulkan/shader_library_vk.h"

#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "impeller/blobcat/blob_library.h"
#include "impeller/renderer/backend/vulkan/shader_function_vk.h"

namespace impeller {

static ShaderStage ToShaderStage(BlobShaderType type) {
  switch (type) {
    case BlobShaderType::kVertex:
      return ShaderStage::kVertex;
    case BlobShaderType::kFragment:
      return ShaderStage::kFragment;
    case BlobShaderType::kCompute:
      return ShaderStage::kCompute;
  }
  FML_UNREACHABLE();
}

static std::string VKShaderNameToShaderKeyName(const std::string& name,
                                               ShaderStage stage) {
  std::stringstream stream;
  stream << name;
  switch (stage) {
    case ShaderStage::kUnknown:
      stream << "_unknown_";
      break;
    case ShaderStage::kVertex:
      stream << "_vertex_";
      break;
    case ShaderStage::kFragment:
      stream << "_fragment_";
      break;
    case ShaderStage::kTessellationControl:
      stream << "_tessellation_control_";
      break;
    case ShaderStage::kTessellationEvaluation:
      stream << "_tessellation_evaluation_";
      break;
    case ShaderStage::kCompute:
      stream << "_compute_";
      break;
  }
  stream << "main";
  return stream.str();
}

ShaderLibraryVK::ShaderLibraryVK(
    const vk::Device& device,
    const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data) {
  TRACE_EVENT0("impeller", "ShaderLibraryCreate");
  ShaderFunctionMap functions;
  bool success = true;
  auto iterator = [&success, &device, &functions, library_id = library_id_](
                      auto type,           //
                      const auto& name,    //
                      const auto& mapping  //
                      ) -> bool {
    vk::ShaderModuleCreateInfo shader_module_info;

    shader_module_info.setPCode(
        reinterpret_cast<const uint32_t*>(mapping->GetMapping()));
    shader_module_info.setCodeSize(mapping->GetSize());

    auto module = device.createShaderModuleUnique(shader_module_info);

    if (module.result != vk::Result::eSuccess) {
      VALIDATION_LOG << "Could not create shader module: "
                     << vk::to_string(module.result);
      success = false;
      return false;
    }

    const auto stage = ToShaderStage(type);
    const auto key_name = VKShaderNameToShaderKeyName(name, stage);

    functions[ShaderKey{key_name, stage}] = std::shared_ptr<ShaderFunctionVK>(
        new ShaderFunctionVK(library_id,              //
                             key_name,                //
                             stage,                   //
                             std::move(module.value)  //
                             ));

    return true;
  };
  for (const auto& library_data : shader_libraries_data) {
    auto blob_library = BlobLibrary{library_data};
    if (!blob_library.IsValid()) {
      VALIDATION_LOG << "Could not construct shader blob library.";
      return;
    }
    blob_library.IterateAllBlobs(iterator);
  }

  if (!success) {
    return;
  }
  functions_ = std::move(functions);
  is_valid_ = true;
}

ShaderLibraryVK::~ShaderLibraryVK() = default;

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

std::shared_ptr<const ShaderFunction> ShaderLibraryVK::GetFunction(
    std::string_view name,
    ShaderStage stage) {
  const auto key = ShaderKey{{name.data(), name.size()}, stage};
  auto found = functions_.find(key);
  if (found != functions_.end()) {
    return found->second;
  }
  return nullptr;
}

}  // namespace impeller
