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

#pragma once

#include "flutter/fml/macros.h"
#include "impeller/renderer/backend/vulkan/vk.h"
#include "impeller/renderer/descriptor_set_layout.h"
#include "impeller/renderer/formats.h"
#include "impeller/renderer/shader_types.h"
#include "vulkan/vulkan_enums.hpp"

namespace impeller {

constexpr vk::SampleCountFlagBits ToVKSampleCountFlagBits(SampleCount count) {
  switch (count) {
    case SampleCount::kCount1:
      return vk::SampleCountFlagBits::e1;
    case SampleCount::kCount4:
      return vk::SampleCountFlagBits::e4;
  }
  FML_UNREACHABLE();
}

constexpr vk::BlendFactor ToVKBlendFactor(BlendFactor factor) {
  switch (factor) {
    case BlendFactor::kZero:
      return vk::BlendFactor::eZero;
    case BlendFactor::kOne:
      return vk::BlendFactor::eOne;
    case BlendFactor::kSourceColor:
      return vk::BlendFactor::eSrcColor;
    case BlendFactor::kOneMinusSourceColor:
      return vk::BlendFactor::eOneMinusSrcColor;
    case BlendFactor::kSourceAlpha:
      return vk::BlendFactor::eSrcAlpha;
    case BlendFactor::kOneMinusSourceAlpha:
      return vk::BlendFactor::eOneMinusSrcAlpha;
    case BlendFactor::kDestinationColor:
      return vk::BlendFactor::eDstColor;
    case BlendFactor::kOneMinusDestinationColor:
      return vk::BlendFactor::eOneMinusDstColor;
    case BlendFactor::kDestinationAlpha:
      return vk::BlendFactor::eDstAlpha;
    case BlendFactor::kOneMinusDestinationAlpha:
      return vk::BlendFactor::eOneMinusDstAlpha;
    case BlendFactor::kSourceAlphaSaturated:
      return vk::BlendFactor::eSrcAlphaSaturate;
    case BlendFactor::kBlendColor:
      return vk::BlendFactor::eConstantColor;
    case BlendFactor::kOneMinusBlendColor:
      return vk::BlendFactor::eOneMinusConstantColor;
    case BlendFactor::kBlendAlpha:
      return vk::BlendFactor::eConstantAlpha;
    case BlendFactor::kOneMinusBlendAlpha:
      return vk::BlendFactor::eOneMinusConstantAlpha;
  }
  FML_UNREACHABLE();
}

constexpr vk::BlendOp ToVKBlendOp(BlendOperation op) {
  switch (op) {
    case BlendOperation::kAdd:
      return vk::BlendOp::eAdd;
    case BlendOperation::kSubtract:
      return vk::BlendOp::eSubtract;
    case BlendOperation::kReverseSubtract:
      return vk::BlendOp::eReverseSubtract;
  }
  FML_UNREACHABLE();
}

constexpr vk::ColorComponentFlags ToVKColorComponentFlags(
    std::underlying_type_t<ColorWriteMask> type) {
  using UnderlyingType = decltype(type);

  vk::ColorComponentFlags mask;

  if (type & static_cast<UnderlyingType>(ColorWriteMask::kRed)) {
    mask |= vk::ColorComponentFlagBits::eR;
  }

  if (type & static_cast<UnderlyingType>(ColorWriteMask::kGreen)) {
    mask |= vk::ColorComponentFlagBits::eG;
  }

  if (type & static_cast<UnderlyingType>(ColorWriteMask::kBlue)) {
    mask |= vk::ColorComponentFlagBits::eB;
  }

  if (type & static_cast<UnderlyingType>(ColorWriteMask::kAlpha)) {
    mask |= vk::ColorComponentFlagBits::eA;
  }

  return mask;
}

constexpr vk::PipelineColorBlendAttachmentState
ToVKPipelineColorBlendAttachmentState(const ColorAttachmentDescriptor& desc) {
  vk::PipelineColorBlendAttachmentState res;

  res.setBlendEnable(desc.blending_enabled);

  res.setSrcColorBlendFactor(ToVKBlendFactor(desc.src_color_blend_factor));
  res.setColorBlendOp(ToVKBlendOp(desc.color_blend_op));
  res.setDstColorBlendFactor(ToVKBlendFactor(desc.dst_color_blend_factor));

  res.setSrcAlphaBlendFactor(ToVKBlendFactor(desc.src_alpha_blend_factor));
  res.setAlphaBlendOp(ToVKBlendOp(desc.alpha_blend_op));
  res.setDstAlphaBlendFactor(ToVKBlendFactor(desc.dst_alpha_blend_factor));

  res.setColorWriteMask(ToVKColorComponentFlags(desc.write_mask));

  return res;
}

constexpr std::optional<vk::ShaderStageFlagBits> ToVKShaderStageFlagBits(
    ShaderStage stage) {
  switch (stage) {
    case ShaderStage::kUnknown:
      return std::nullopt;
    case ShaderStage::kVertex:
      return vk::ShaderStageFlagBits::eVertex;
    case ShaderStage::kFragment:
      return vk::ShaderStageFlagBits::eFragment;
    case ShaderStage::kTessellationControl:
      return vk::ShaderStageFlagBits::eTessellationControl;
    case ShaderStage::kTessellationEvaluation:
      return vk::ShaderStageFlagBits::eTessellationEvaluation;
    case ShaderStage::kCompute:
      return vk::ShaderStageFlagBits::eCompute;
  }
  FML_UNREACHABLE();
}

constexpr vk::Format ToVKImageFormat(PixelFormat format) {
  switch (format) {
    case PixelFormat::kUnknown:
      return vk::Format::eUndefined;
    case PixelFormat::kA8UNormInt:
      return vk::Format::eR8Unorm;
    case PixelFormat::kR8G8B8A8UNormInt:
      return vk::Format::eR8G8B8A8Unorm;
    case PixelFormat::kR8G8B8A8UNormIntSRGB:
      return vk::Format::eR8G8B8A8Srgb;
    case PixelFormat::kB8G8R8A8UNormInt:
      return vk::Format::eB8G8R8A8Unorm;
    case PixelFormat::kB8G8R8A8UNormIntSRGB:
      return vk::Format::eB8G8R8A8Srgb;
    case PixelFormat::kS8UInt:
      return vk::Format::eS8Uint;
    case PixelFormat::kR8UNormInt:
      return vk::Format::eR8Unorm;
    case PixelFormat::kR8G8UNormInt:
      return vk::Format::eR8G8Unorm;
  }

  FML_UNREACHABLE();
}

constexpr PixelFormat ToPixelFormat(vk::Format format) {
  switch (format) {
    case vk::Format::eUndefined:
      return PixelFormat::kUnknown;

    case vk::Format::eR8G8B8A8Unorm:
      return PixelFormat::kR8G8B8A8UNormInt;

    case vk::Format::eR8G8B8A8Srgb:
      return PixelFormat::kR8G8B8A8UNormIntSRGB;

    case vk::Format::eB8G8R8A8Unorm:
      return PixelFormat::kB8G8R8A8UNormInt;

    case vk::Format::eB8G8R8A8Srgb:
      return PixelFormat::kB8G8R8A8UNormIntSRGB;

    case vk::Format::eS8Uint:
      return PixelFormat::kS8UInt;

    case vk::Format::eR8Unorm:
      return PixelFormat::kR8UNormInt;

    case vk::Format::eR8G8Unorm:
      return PixelFormat::kR8G8UNormInt;

    default:
      return PixelFormat::kUnknown;
  }
}

constexpr vk::SampleCountFlagBits ToVKSampleCount(SampleCount sample_count) {
  switch (sample_count) {
    case SampleCount::kCount1:
      return vk::SampleCountFlagBits::e1;
    case SampleCount::kCount4:
      return vk::SampleCountFlagBits::e4;
  }
}

constexpr vk::Filter ToVKSamplerMinMagFilter(MinMagFilter filter) {
  switch (filter) {
    case MinMagFilter::kNearest:
      return vk::Filter::eNearest;
    case MinMagFilter::kLinear:
      return vk::Filter::eLinear;
  }

  FML_UNREACHABLE();
}

constexpr vk::SamplerMipmapMode ToVKSamplerMipmapMode(MipFilter filter) {
  vk::SamplerCreateInfo sampler_info;
  switch (filter) {
    case MipFilter::kNearest:
      return vk::SamplerMipmapMode::eNearest;
    case MipFilter::kLinear:
      return vk::SamplerMipmapMode::eLinear;
    case MipFilter::kNone:
      return vk::SamplerMipmapMode::eNearest;
  }

  FML_UNREACHABLE();
}

constexpr vk::SamplerAddressMode ToVKSamplerAddressMode(
    SamplerAddressMode mode) {
  switch (mode) {
    case SamplerAddressMode::kRepeat:
      return vk::SamplerAddressMode::eRepeat;
    case SamplerAddressMode::kMirror:
      return vk::SamplerAddressMode::eMirroredRepeat;
    case SamplerAddressMode::kClampToEdge:
      return vk::SamplerAddressMode::eClampToEdge;
  }

  FML_UNREACHABLE();
}

constexpr vk::ShaderStageFlags ToVkShaderStage(ShaderStage stage) {
  switch (stage) {
    case ShaderStage::kUnknown:
      return vk::ShaderStageFlagBits::eAll;
    case ShaderStage::kFragment:
      return vk::ShaderStageFlagBits::eFragment;
    case ShaderStage::kTessellationControl:
      return vk::ShaderStageFlagBits::eTessellationControl;
    case ShaderStage::kTessellationEvaluation:
      return vk::ShaderStageFlagBits::eTessellationEvaluation;
    case ShaderStage::kCompute:
      return vk::ShaderStageFlagBits::eCompute;
    case ShaderStage::kVertex:
      return vk::ShaderStageFlagBits::eVertex;
  }

  FML_UNREACHABLE();
}

constexpr vk::DescriptorSetLayoutBinding ToVKDescriptorSetLayoutBinding(
    const DescriptorSetLayout& layout) {
  vk::DescriptorSetLayoutBinding binding;
  binding.binding = layout.binding;
  binding.descriptorCount = layout.descriptor_count;
  vk::DescriptorType desc_type = vk::DescriptorType();
  switch (layout.descriptor_type) {
    case DescriptorType::kSampledImage:
      desc_type = vk::DescriptorType::eCombinedImageSampler;
      break;
    case DescriptorType::kUniformBuffer:
      desc_type = vk::DescriptorType::eUniformBuffer;
      break;
  }
  binding.descriptorType = desc_type;
  binding.stageFlags = ToVkShaderStage(layout.shader_stage);
  return binding;
}

constexpr vk::AttachmentLoadOp ToVKAttachmentLoadOp(LoadAction load_action) {
  switch (load_action) {
    case LoadAction::kLoad:
      return vk::AttachmentLoadOp::eLoad;
    case LoadAction::kClear:
      return vk::AttachmentLoadOp::eClear;
    case LoadAction::kDontCare:
      return vk::AttachmentLoadOp::eDontCare;
  }

  FML_UNREACHABLE();
}

constexpr vk::AttachmentStoreOp ToVKAttachmentStoreOp(
    StoreAction store_action) {
  switch (store_action) {
    case StoreAction::kStore:
      return vk::AttachmentStoreOp::eStore;
    case StoreAction::kDontCare:
      return vk::AttachmentStoreOp::eDontCare;
    case StoreAction::kMultisampleResolve:
    case StoreAction::kStoreAndMultisampleResolve:
      // TODO (kaushikiska): vulkan doesn't support multisample resolve.
      return vk::AttachmentStoreOp::eDontCare;
  }

  FML_UNREACHABLE();
}

constexpr vk::IndexType ToVKIndexType(IndexType index_type) {
  switch (index_type) {
    case IndexType::k16bit:
      return vk::IndexType::eUint16;
    case IndexType::k32bit:
      return vk::IndexType::eUint32;
    case IndexType::kUnknown:
      return vk::IndexType::eUint32;
  }

  FML_UNREACHABLE();
}

constexpr vk::PrimitiveTopology ToVKPrimitiveTopology(PrimitiveType primitive) {
  switch (primitive) {
    case PrimitiveType::kTriangle:
      return vk::PrimitiveTopology::eTriangleList;
    case PrimitiveType::kTriangleStrip:
      return vk::PrimitiveTopology::eTriangleStrip;
    case PrimitiveType::kLine:
      return vk::PrimitiveTopology::eLineList;
    case PrimitiveType::kLineStrip:
      return vk::PrimitiveTopology::eLineStrip;
    case PrimitiveType::kPoint:
      return vk::PrimitiveTopology::ePointList;
  }

  FML_UNREACHABLE();
}

}  // namespace impeller
