// 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 "mesh_example.h"

#include <array>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <iterator>

#include "imgui/imgui.h"
#include "impeller/core/allocator.h"
#include "impeller/core/buffer_view.h"
#include "impeller/core/device_buffer_descriptor.h"
#include "impeller/core/formats.h"
#include "impeller/core/host_buffer.h"
#include "impeller/core/vertex_buffer.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/pipeline_library.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/render_target.h"
#include "impeller/renderer/sampler_library.h"
#include "impeller/tessellator/tessellator.h"

#include "examples/assets.h"

#include "generated/importer/mesh_flatbuffers.h"
#include "generated/shaders/mesh_example.frag.h"
#include "generated/shaders/mesh_example.vert.h"

namespace example {

ExampleBase::Info MeshExample::GetInfo() {
  return {
      .name = "Mesh Example",
      .description =
          "An FBX with texture coordinates and normals/tangents imported ahead "
          "of time. The importer tool is located under `src/importer`.",
  };
}

bool MeshExample::Setup(impeller::Context& context) {
  transients_buffer_ =
      impeller::HostBuffer::Create(context.GetResourceAllocator());

  //----------------------------------------------------------------------------
  /// Load/unpack the model.
  ///

  std::ifstream in;
  const char* filename = "assets/flutter_logo.model";
  in.open(filename, std::ios::binary | std::ios::in);
  in.seekg(0, std::ios::end);
  auto size = in.tellg();
  in.seekg(0, std::ios::beg);

  std::vector<char> data(size);
  in.read(data.data(), size);
  in.close();

  if (!in) {
    std::cerr << "Failed to read file: " << filename << std::endl;
    return false;
  }

  fb::MeshT mesh;
  fb::GetMesh(data.data())->UnPackTo(&mesh);

  //----------------------------------------------------------------------------
  /// Load textures.
  ///

  const auto asset_path = std::filesystem::current_path() / "assets/";

  base_color_texture_ =
      example::LoadTexture(asset_path / "flutter_logo_BaseColor.png",
                           *context.GetResourceAllocator());
  if (!base_color_texture_) {
    std::cerr << "Failed to load base color texture." << std::endl;
  }

  normal_texture_ = example::LoadTexture(asset_path / "flutter_logo_Normal.png",
                                         *context.GetResourceAllocator());
  if (!normal_texture_) {
    std::cerr << "Failed to load normal texture." << std::endl;
  }

  occlusion_roughness_metallic_texture_ = example::LoadTexture(
      asset_path / "flutter_logo_OcclusionRoughnessMetallic.png",
      *context.GetResourceAllocator());
  if (!occlusion_roughness_metallic_texture_) {
    std::cerr << "Failed to load occlusion/roughness/metallic texture."
              << std::endl;
  }

  //----------------------------------------------------------------------------
  /// Upload vertices/indices to the device.
  ///

  auto vertices_size = sizeof(fb::Vertex) * mesh.vertices.size();
  auto indices_size = sizeof(uint16_t) * mesh.indices.size();

  auto device_buffer = context.GetResourceAllocator()->CreateBuffer({
      .storage_mode = impeller::StorageMode::kHostVisible,
      .size = vertices_size + indices_size,
  });

  if (!device_buffer) {
    std::cerr << "Failed to create device buffer." << std::endl;
    return false;
  }

  if (!device_buffer->CopyHostBuffer(
          reinterpret_cast<uint8_t*>(mesh.vertices.data()),
          impeller::Range{0, vertices_size}, 0)) {
    std::cerr << "Failed to upload vertices to device buffer." << std::endl;
    return false;
  }

  if (!device_buffer->CopyHostBuffer(
          reinterpret_cast<uint8_t*>(mesh.indices.data()),
          impeller::Range{0, indices_size}, vertices_size)) {
    std::cerr << "Failed to upload indices to device buffer." << std::endl;
    return false;
  }

  vertex_buffer_ = {
      .vertex_buffer =
          impeller::BufferView{.buffer = device_buffer,
                               .range = impeller::Range{0, vertices_size}},
      .index_buffer =
          impeller::BufferView{
              .buffer = device_buffer,
              .range = impeller::Range{vertices_size, indices_size}},
      .vertex_count = mesh.indices.size(),
      .index_type = impeller::IndexType::k16bit,
  };

  //----------------------------------------------------------------------------
  /// Build the pipeline.
  ///

  auto pipeline_desc =
      impeller::PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(context);
  pipeline_desc->SetSampleCount(impeller::SampleCount::kCount4);
  pipeline_desc->SetWindingOrder(impeller::WindingOrder::kClockwise);
  pipeline_desc->SetCullMode(impeller::CullMode::kBackFace);
  pipeline_desc->SetDepthStencilAttachmentDescriptor(
      std::make_optional<impeller::DepthAttachmentDescriptor>({
          .depth_compare = impeller::CompareFunction::kLess,
          .depth_write_enabled = true,
      }));
  pipeline_ = context.GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
  if (!pipeline_ || !pipeline_->IsValid()) {
    std::cerr << "Failed to initialize pipeline for mesh example.";
    return false;
  }

  return true;
}

bool MeshExample::Render(impeller::Context& context,
                         const impeller::RenderTarget& render_target,
                         impeller::CommandBuffer& command_buffer) {
  clock_.Tick();
  transients_buffer_->Reset();

  static float exposure = 5;
  ImGui::SliderFloat("Exposure", &exposure, 0, 15);

  auto pass = command_buffer.CreateRenderPass(render_target);
  if (!pass) {
    return false;
  }

  pass->SetCommandLabel("Mesh Example");
  pass->SetPipeline(pipeline_);

  pass->SetVertexBuffer(vertex_buffer_);

  auto time = clock_.GetTime();

  VS::VertInfo vs_uniform;
  vs_uniform.mvp =
      impeller::Matrix::MakePerspective(
          impeller::Degrees{60}, pass->GetRenderTargetSize(), 0.1, 1000) *
      impeller::Matrix::MakeLookAt({0, 0, -50}, {0, 0, 0}, {0, 1, 0}) *
      impeller::Matrix::MakeScale({0.3, 0.3, 0.3}) *
      impeller::Matrix::MakeRotationY(impeller::Radians{-0.4f * time}) *
      impeller::Matrix::MakeRotationZ(
          impeller::Radians{std::sin(time * 0.43f) / 5}) *
      impeller::Matrix::MakeRotationX(
          impeller::Radians{std::cos(time * 0.27f) / 4});

  VS::BindVertInfo(*pass, transients_buffer_->EmplaceUniform(vs_uniform));

  FS::FragInfo fs_uniform;
  fs_uniform.exposure = exposure;
  fs_uniform.camera_position = {0, 0, -50};
  FS::BindFragInfo(*pass, transients_buffer_->EmplaceUniform(fs_uniform));

  impeller::SamplerDescriptor sampler_desc;
  sampler_desc.min_filter = impeller::MinMagFilter::kLinear;
  sampler_desc.mag_filter = impeller::MinMagFilter::kLinear;
  const auto& sampler = context.GetSamplerLibrary()->GetSampler(sampler_desc);
  FS::BindBaseColorTexture(*pass, base_color_texture_, sampler);
  FS::BindNormalTexture(*pass, normal_texture_, sampler);
  FS::BindOcclusionRoughnessMetallicTexture(
      *pass, occlusion_roughness_metallic_texture_, sampler);

  if (!pass->Draw().ok()) {
    return false;
  }

  if (!pass->EncodeCommands()) {
    return false;
  }

  return true;
}

}  // namespace example
