// 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/entity/geometry.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/position_color.vert.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/renderer/device_buffer.h"
#include "impeller/tessellator/tessellator.h"

namespace impeller {

Geometry::Geometry() = default;

Geometry::~Geometry() = default;

// static
std::unique_ptr<Geometry> Geometry::MakeVertices(Vertices vertices) {
  return std::make_unique<VerticesGeometry>(std::move(vertices));
}

std::unique_ptr<Geometry> Geometry::MakePath(Path path) {
  return std::make_unique<PathGeometry>(std::move(path));
}

std::unique_ptr<Geometry> Geometry::MakeCover() {
  return std::make_unique<CoverGeometry>();
}

/////// Vertices Geometry ///////

VerticesGeometry::VerticesGeometry(Vertices vertices)
    : vertices_(std::move(vertices)) {}

VerticesGeometry::~VerticesGeometry() = default;

static PrimitiveType GetPrimitiveType(const Vertices& vertices) {
  switch (vertices.GetMode()) {
    case VertexMode::kTriangle:
      return PrimitiveType::kTriangle;
    case VertexMode::kTriangleStrip:
      return PrimitiveType::kTriangleStrip;
  }
}

GeometryResult VerticesGeometry::GetPositionBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  if (!vertices_.IsValid()) {
    return {};
  }

  auto vertex_count = vertices_.GetPositions().size();
  size_t total_vtx_bytes = vertex_count * sizeof(float) * 2;
  size_t total_idx_bytes = vertices_.GetIndices().size() * sizeof(uint16_t);

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total_vtx_bytes + total_idx_bytes;
  buffer_desc.storage_mode = StorageMode::kHostVisible;

  auto buffer = device_allocator->CreateBuffer(buffer_desc);

  const auto& positions = vertices_.GetPositions();
  if (!buffer->CopyHostBuffer(
          reinterpret_cast<const uint8_t*>(positions.data()),
          Range{0, total_vtx_bytes}, 0)) {
    return {};
  }
  if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(
                                  vertices_.GetIndices().data())),
                              Range{0, total_idx_bytes}, total_vtx_bytes)) {
    return {};
  }

  return GeometryResult{
      .type = GetPrimitiveType(vertices_),
      .vertex_buffer =
          {
              .vertex_buffer = {.buffer = buffer,
                                .range = Range{0, total_vtx_bytes}},
              .index_buffer = {.buffer = buffer,
                               .range =
                                   Range{total_vtx_bytes, total_idx_bytes}},
              .index_count = vertices_.GetIndices().size(),
              .index_type = IndexType::k16bit,
          },
      .prevent_overdraw = false,
  };
}

GeometryResult VerticesGeometry::GetPositionColorBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    Color paint_color,
    BlendMode blend_mode) {
  using VS = GeometryColorPipeline::VertexShader;

  if (!vertices_.IsValid()) {
    return {};
  }

  auto vertex_count = vertices_.GetPositions().size();
  std::vector<VS::PerVertexData> vertex_data(vertex_count);
  {
    const auto& positions = vertices_.GetPositions();
    const auto& colors = vertices_.GetColors();
    for (size_t i = 0; i < vertex_count; i++) {
      auto color = Color::BlendColor(paint_color, colors[i], blend_mode);
      vertex_data[i] = {
          .position = positions[i],
          .color = color,
      };
    }
  }

  size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData);
  size_t total_idx_bytes = vertices_.GetIndices().size() * sizeof(uint16_t);

  DeviceBufferDescriptor buffer_desc;
  buffer_desc.size = total_vtx_bytes + total_idx_bytes;
  buffer_desc.storage_mode = StorageMode::kHostVisible;

  auto buffer = device_allocator->CreateBuffer(buffer_desc);

  if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(vertex_data.data()),
                              Range{0, total_vtx_bytes}, 0)) {
    return {};
  }
  if (!buffer->CopyHostBuffer(reinterpret_cast<uint8_t*>(const_cast<uint16_t*>(
                                  vertices_.GetIndices().data())),
                              Range{0, total_idx_bytes}, total_vtx_bytes)) {
    return {};
  }

  return GeometryResult{
      .type = GetPrimitiveType(vertices_),
      .vertex_buffer =
          {
              .vertex_buffer = {.buffer = buffer,
                                .range = Range{0, total_vtx_bytes}},
              .index_buffer = {.buffer = buffer,
                               .range =
                                   Range{total_vtx_bytes, total_idx_bytes}},
              .index_count = vertices_.GetIndices().size(),
              .index_type = IndexType::k16bit,
          },
      .prevent_overdraw = false,
  };
}

GeometryResult VerticesGeometry::GetPositionUVBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  // TODO(jonahwilliams): support texture coordinates in vertices.
  return {};
}

GeometryVertexType VerticesGeometry::GetVertexType() {
  if (vertices_.GetColors().size()) {
    return GeometryVertexType::kColor;
  }
  return GeometryVertexType::kPosition;
}

std::optional<Rect> VerticesGeometry::GetCoverage(Matrix transform) {
  return vertices_.GetTransformedBoundingBox(transform);
}

/////// Path Geometry ///////

PathGeometry::PathGeometry(Path path) : path_(std::move(path)) {}

PathGeometry::~PathGeometry() = default;

GeometryResult PathGeometry::GetPositionBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  VertexBuffer vertex_buffer;
  auto tesselation_result = tessellator->TessellateBuilder(
      path_.GetFillType(), path_.CreatePolyline(),
      [&vertex_buffer, &host_buffer](
          const float* vertices, size_t vertices_count, const uint16_t* indices,
          size_t indices_count) {
        vertex_buffer.vertex_buffer = host_buffer.Emplace(
            vertices, vertices_count * sizeof(float), alignof(float));
        vertex_buffer.index_buffer = host_buffer.Emplace(
            indices, indices_count * sizeof(uint16_t), alignof(uint16_t));
        vertex_buffer.index_count = indices_count;
        vertex_buffer.index_type = IndexType::k16bit;
        return true;
      });
  if (tesselation_result != Tessellator::Result::kSuccess) {
    return {};
  }
  return GeometryResult{
      .type = PrimitiveType::kTriangle,
      .vertex_buffer = vertex_buffer,
      .prevent_overdraw = false,
  };
}

GeometryResult PathGeometry::GetPositionColorBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    Color paint_color,
    BlendMode blend_mode) {
  // TODO(jonahwilliams): support per-color vertex in path geometry.
  return {};
}

GeometryResult PathGeometry::GetPositionUVBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  // TODO(jonahwilliams): support texture coordinates in path geometry.
  return {};
}

GeometryVertexType PathGeometry::GetVertexType() {
  return GeometryVertexType::kPosition;
}

std::optional<Rect> PathGeometry::GetCoverage(Matrix transform) {
  return path_.GetTransformedBoundingBox(transform);
}

/////// Cover Geometry ///////

CoverGeometry::CoverGeometry() = default;

CoverGeometry::~CoverGeometry() = default;

GeometryResult CoverGeometry::GetPositionBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  auto rect = Rect(Size(render_target_size));
  constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3};
  return GeometryResult{
      .type = PrimitiveType::kTriangleStrip,
      .vertex_buffer = {.vertex_buffer = host_buffer.Emplace(
                            rect.GetPoints().data(), 8 * sizeof(float),
                            alignof(float)),
                        .index_buffer = host_buffer.Emplace(
                            kRectIndicies, 4 * sizeof(uint16_t),
                            alignof(uint16_t)),
                        .index_count = 4,
                        .index_type = IndexType::k16bit},
      .prevent_overdraw = false,
  };
}

GeometryResult CoverGeometry::GetPositionColorBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    Color paint_color,
    BlendMode blend_mode) {
  // TODO(jonahwilliams): support per-color vertex in cover geometry.
  return {};
}

GeometryResult CoverGeometry::GetPositionUVBuffer(
    std::shared_ptr<Allocator> device_allocator,
    HostBuffer& host_buffer,
    std::shared_ptr<Tessellator> tessellator,
    ISize render_target_size) {
  // TODO(jonahwilliams): support texture coordinates in cover geometry.
  return {};
}

GeometryVertexType CoverGeometry::GetVertexType() {
  return GeometryVertexType::kPosition;
}

std::optional<Rect> CoverGeometry::GetCoverage(Matrix transform) {
  return Rect::MakeMaximum();
}

}  // namespace impeller
