// Copyright 2018 The Fuchsia 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 "src/ui/examples/lab/pose_buffer_presenter/app.h"

// This header is intentionally out of order because it contains a workaround
// for both glm and zircon defining countof(), and must be included before
// the glm headers to work.
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/cpp/task.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/zx/clock.h>

// clang-format off
#include "src/ui/lib/glm_workaround/glm_workaround.h"
// clang-format on

#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/string_cast.hpp>
#include <iostream>

#include "lib/ui/scenic/cpp/commands.h"
#include "src/lib/ui/scenic/cpp/host_memory.h"
#include "src/lib/ui/scenic/cpp/mesh_utils.h"
#include <lib/syslog/cpp/macros.h>
#include "src/ui/lib/escher/geometry/types.h"
#include "src/ui/lib/escher/hmd/pose_buffer.h"
#include "src/ui/lib/escher/util/image_utils.h"

#define DEBUG_BOX 0

using namespace scenic;

namespace pose_buffer_presenter {

namespace {

constexpr float kSecondsPerNanosecond = .000'000'001f;

static constexpr float kEdgeLength = 0.125f;

static const float kVertexBufferData[] = {
    -1.0f, -1.0f, -1.0f,  // 0
    -1.0f, -1.0f, 1.0f,   // 1
    -1.0f, 1.0f,  -1.0f,  // 2
    -1.0f, 1.0f,  1.0f,   // 3
    1.0f,  -1.0f, -1.0f,  // 4
    1.0f,  -1.0f, 1.0f,   // 5
    1.0f,  1.0f,  -1.0f,  // 6
    1.0f,  1.0f,  1.0f,   // 7
};

static const uint32_t kIndexBufferData[] = {
    5, 6, 7, 6, 5, 4,  // +X
    0, 1, 2, 3, 2, 1,  // -X
    2, 3, 6, 7, 6, 3,  // +Y
    1, 4, 5, 4, 1, 0,  // -Y
    3, 5, 7, 5, 3, 1,  // +Z
    0, 2, 4, 6, 4, 2,  // -Z
};
}  // namespace

App::App(async::Loop* loop)
    : component_context_(sys::ComponentContext::CreateAndServeOutgoingDirectory()), loop_(loop) {
  // Connect to the Scenic service.
  scenic_ = component_context_->svc()->Connect<fuchsia::ui::scenic::Scenic>();
  scenic_.set_error_handler([this](zx_status_t status) {
    FX_LOGS(INFO) << "Lost connection to Scenic service. Status: " << status;
    loop_->Quit();
  });
  scenic_->GetDisplayInfo(
      [this](fuchsia::ui::gfx::DisplayInfo display_info) { Init(std::move(display_info)); });
}

void App::CreateExampleScene(float display_width, float display_height) {
  auto session = session_.get();

  // The top-level nesting for drawing anything is compositor -> layer-stack
  // -> layer.  Layer content can come from an image, or by rendering a scene.
  // In this case, we do the latter, so we nest layer -> renderer -> camera ->
  // scene.
  compositor_ = std::make_unique<DisplayCompositor>(session);
  LayerStack layer_stack(session);
  Layer layer(session);
  Renderer renderer(session);
  Scene scene(session);
  camera_ = std::make_unique<StereoCamera>(scene);

  // Produces the Identity View Matrix
  static const glm::vec3 eye(0, 0, 0);
  static const glm::vec3 look_at(0, 0, -1);
  static const glm::vec3 up(0, 1, 0);
  camera_->SetTransform({eye.x, eye.y, eye.z}, {look_at.x, look_at.y, look_at.z},
                        {up.x, up.y, up.z});

  float fovy = glm::radians(30.f);
  float f = 1.0f / tan(0.5f * fovy);
  float aspect_ratio = (display_width * 0.5f) / display_height;
  float near = 0.1f;
  float far = 10;
  // Use (display_width * 0.5f) / display_height because the stereo camera uses
  // half of the display for each eye, so the aspect ratio for each eye has 1/2
  // the width:height ratio of the display.
  // clang-format off
  glm::mat4 projection( f / aspect_ratio,  0.0f, 0.0f,                        0.0f,
                        0.0f,                -f, 0.0f,                        0.0f,
                        0.0f,              0.0f, far / (near - far),         -1.0f,
                        0.0f,              0.0f, (near * far) / (near - far), 0.0f);
  // clang-format on
  std::array<float, 16> projection_arr;
  const float* projection_ptr = glm::value_ptr(projection);
  std::copy(projection_ptr, projection_ptr + 16, std::begin(projection_arr));
  camera_->SetStereoProjection(projection_arr, projection_arr);

  compositor_->SetLayerStack(layer_stack);
  layer_stack.AddLayer(layer);
  layer.SetSize(display_width, display_height);
  layer.SetRenderer(renderer);
  renderer.SetCamera(camera_->id());
  renderer.SetShadowTechnique(fuchsia::ui::gfx::ShadowTechnique::UNSHADOWED);

  // Set up lights.
  AmbientLight ambient_light(session);
  DirectionalLight directional_light(session);
  scene.AddLight(ambient_light);
  scene.AddLight(directional_light);
  ambient_light.SetColor(0.3f, 0.3f, 0.3f);
  directional_light.SetColor(0.7f, 0.7f, 0.7f);
  directional_light.SetDirection(1.f, 1.f, -2.f);

  // Create an EntityNode to serve as the scene root.
  EntityNode root_node(session);
  scene.AddChild(root_node.id());

  cube_node_ = std::make_unique<ShapeNode>(session);
  Material cube_material(session);
  cube_material.SetColor(0xf5, 0x00, 0x57, 0xff);  // Pink A400
  cube_node_->SetMaterial(cube_material);

  std::vector<float> vertices(std::begin(kVertexBufferData), std::end(kVertexBufferData));
  std::vector<uint32_t> indices(std::begin(kIndexBufferData), std::end(kIndexBufferData));
  auto cube_shape = scenic_util::NewMeshWithVertices(session, vertices, indices);

  cube_node_->SetShape(*cube_shape);
  // Raw vertex data has an edge length of 2, so we must scale by half of
  // kEdgeLength to end up with a cube whose edge length is kEdgeLength long.
  float scale_factor = 0.5 * kEdgeLength;
  cube_node_->SetScale(scale_factor, scale_factor, scale_factor);
  cube_node_->SetTranslation(0, 4.0 * kEdgeLength, 0);

  root_node.AddChild(*cube_node_);

// Adds a colored box arround the camera to help debug orientation problems
#if DEBUG_BOX
  float pane_width = 10;
  scenic::Rectangle pane_shape(session, pane_width, pane_width);

  static const int num_panes = 6;

  glm::vec4 colors[num_panes] = {
      glm::vec4(255, 0, 0, 255),    // RED
      glm::vec4(0, 255, 255, 255),  // CYAN
      glm::vec4(0, 255, 0, 255),    // GREEN
      glm::vec4(255, 0, 255, 255),  // MAGENTA
      glm::vec4(0, 0, 255, 255),    // BLUE
      glm::vec4(255, 255, 0, 255),  // YELLOW
  };

  static const float pane_offset = pane_width / 2;

  glm::vec3 translations[num_panes] = {
      glm::vec3(0, 0, pane_offset),   // Above Camera
      glm::vec3(0, 0, -pane_offset),  // Below Camera
      glm::vec3(pane_offset, 0, 0),   // Right of camera
      glm::vec3(-pane_offset, 0, 0),  // Left of Camera
      glm::vec3(0, pane_offset, 0),   // In front of camera.
      glm::vec3(0, -pane_offset, 0),  // Behind camera.
  };

  float pi = glm::pi<float>();
  glm::quat orientations[num_panes] = {
      glm::quat(),  // identity quaternion
      glm::angleAxis(pi, glm::vec3(1, 0, 0)),
      glm::angleAxis(pi / 2, glm::vec3(0, 1, 0)),
      glm::angleAxis(-pi / 2, glm::vec3(0, 1, 0)),
      glm::angleAxis(-pi / 2, glm::vec3(1, 0, 0)),
      glm::angleAxis(pi / 2, glm::vec3(1, 0, 0)),

  };

  for (int i = 0; i < num_panes; i++) {
    glm::vec4 color = colors[i];
    glm::vec3 translation = translations[i];
    glm::quat orientation = orientations[i];

    scenic::Material pane_material(session);
    pane_material.SetColor(color.r, color.g, color.b, color.a);
    scenic::ShapeNode pane_shape_node(session);
    pane_shape_node.SetShape(pane_shape);
    pane_shape_node.SetMaterial(pane_material);
    pane_shape_node.SetTranslation(translation.x, translation.y, translation.z);
    pane_shape_node.SetRotation(orientation.x, orientation.y, orientation.z, orientation.w);
    root_node.AddChild(pane_shape_node);
  }
#endif
}

void App::StartPoseBufferProvider() {
  FX_LOGS(INFO) << "Launching PoseBufferProvider";

  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url =
      "fuchsia-pkg://fuchsia.com/pose_buffer_provider#meta/"
      "pose_buffer_provider.cmx";
  auto services = sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);
  fuchsia::sys::LauncherSyncPtr launcher;
  component_context_->svc()->Connect(launcher.NewRequest());
  launcher->CreateComponent(std::move(launch_info), controller_.NewRequest());
  controller_.set_error_handler([](zx_status_t status) {
    FX_LOGS(ERROR) << "Lost connection to controller_. Status: " << status;
  });

  services->Connect(provider_.NewRequest());
  provider_.set_error_handler([](zx_status_t status) {
    FX_LOGS(ERROR) << "Lost connection to PoseBufferProvider service. Status: " << status;
  });
}

void App::ConfigurePoseBuffer() {
  auto session = session_.get();

  uint64_t vmo_size = PAGE_SIZE;
  zx::vmo vmo;
  zx_status_t status;
  status = zx::vmo::create(vmo_size, 0u, &pose_buffer_vmo_);
  FX_DCHECK(status == ZX_OK);
  status = pose_buffer_vmo_.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
  FX_DCHECK(status == ZX_OK);

  zx_time_t base_time = zx::clock::get_monotonic().get();
  // Normally the time interval is the period of time between each entry in the
  // pose buffer. In this example we only use one entry so the time interval is
  // pretty meaningless. Set to 1 for simplicity (see fxbug.dev/327).
  zx_time_t time_interval = 1;
  uint32_t num_entries = 1;

  Memory mem(session, std::move(vmo), vmo_size, fuchsia::images::MemoryType::VK_DEVICE_MEMORY);
  Buffer pose_buffer(mem, 0, vmo_size);

  camera_->SetPoseBuffer(pose_buffer, num_entries, base_time, time_interval);

  status = pose_buffer_vmo_.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
  FX_DCHECK(status == ZX_OK);

  provider_->SetPoseBuffer(std::move(vmo), num_entries, base_time, time_interval);
}

void App::Init(fuchsia::ui::gfx::DisplayInfo display_info) {
  StartPoseBufferProvider();
  FX_LOGS(INFO) << "Creating new Session";

  // TODO: set up SessionListener.
  session_ = std::make_unique<Session>(scenic_.get());
  session_->set_error_handler([this](zx_status_t status) {
    FX_LOGS(INFO) << "Session terminated. Status: " << status;
    loop_->Quit();
  });

  // Set up initial scene.
  const float display_width = static_cast<float>(display_info.width_in_px);
  const float display_height = static_cast<float>(display_info.height_in_px);
  CreateExampleScene(display_width, display_height);
  ConfigurePoseBuffer();

  start_time_ = zx_clock_get_monotonic();
  Update(start_time_);
}

void App::Update(uint64_t next_presentation_time) {
  float secs =
      static_cast<float>(static_cast<double>(zx_clock_get_monotonic()) * kSecondsPerNanosecond);

  glm::quat quaternion = glm::angleAxis(secs / 2.0f, glm::normalize(glm::vec3(0, 1, 0)));

  cube_node_->SetRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w);

  // Present
  session_->Present(next_presentation_time, [this](fuchsia::images::PresentationInfo info) {
    Update(info.presentation_time + info.presentation_interval);
  });
}

void App::ReleaseSessionResources() {
  FX_LOGS(INFO) << "Closing session.";

  compositor_.reset();
  camera_.reset();

  session_.reset();
}

}  // namespace pose_buffer_presenter
