// 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 <cstdlib>
#include <iostream>
#include <memory>

#include <fuchsia/ui/viewsv1/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <png.h>
#include <trace-provider/provider.h>

#include "garnet/lib/ui/gfx/resources/snapshot/snapshot_generated.h"
#include "garnet/lib/ui/gfx/resources/snapshot/version.h"
#include "lib/component/cpp/startup_context.h"
#include "lib/fsl/vmo/vector.h"
#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
#include "src/lib/fxl/logging.h"
#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include "third_party/cobalt/util/crypto_util/base64.h"

using cobalt::crypto::Base64Encode;
using namespace rapidjson;
using namespace scenic_impl::gfx;

const char *EMPTY_GLTF_DOC = R"glTF({
  "scenes": [{
    "nodes": []
  }],
  "scene": 0,
  "nodes": [],
  "meshes": [],
  "buffers": [],
  "bufferViews": [],
  "accessors": [],
  "materials": [],
  "textures": [],
  "images": [],
  "samplers": [{}],
  "asset": {
    "version": "2.0"
  }
})glTF";

const char *EMPTY_TEXTURE_MATERIAL = R"glTF({
   "pbrMetallicRoughness" : {
    "baseColorTexture" : {
    },
    "metallicFactor" : 0.0,
    "roughnessFactor" : 1.0
  }
})glTF";

const char *EMPTY_COLOR_MATERIAL = R"glTF({
   "pbrMetallicRoughness" : {
    "baseColorFactor" : [1.0, 1.0, 1.0, 1.0],
    "metallicFactor" : 0.0,
    "roughnessFactor" : 1.0
  }
})glTF";

// Converts uncompressed raw image to PNG.
bool RawToPNG(size_t width, size_t height, const uint8_t *data,
              std::vector<uint8_t> &out);

// Dumps rapidjson Value to ostream.
std::ostream &operator<<(std::ostream &os, const Value &v) {
  StringBuffer buffer;
  PrettyWriter<StringBuffer> writer(buffer);
  v.Accept(writer);
  return os << buffer.GetString();
}

// Defines a class to take a snapshot of the current scenic composition.
class SnapshotTaker {
 public:
  explicit SnapshotTaker(async::Loop *loop)
      : loop_(loop),
        context_(component::StartupContext::CreateFromStartupInfo()) {
    // Connect to the Scenic service.
    scenic_ =
        context_->ConnectToEnvironmentService<fuchsia::ui::scenic::Scenic>();
    scenic_.set_error_handler([this](zx_status_t status) {
      FXL_LOG(ERROR) << "Lost connection to Scenic service.";
      encountered_error_ = true;
      loop_->Quit();
    });

    // Connect to the ViewSnapshot service.
    view_snapshot_ =
        context_
            ->ConnectToEnvironmentService<fuchsia::ui::viewsv1::ViewSnapshot>();
    view_snapshot_.set_error_handler([this](zx_status_t status) {
      FXL_LOG(ERROR) << "Lost connection to Snapshot service.";
      encountered_error_ = true;
      loop_->Quit();
    });
  }

  bool encountered_error() const { return encountered_error_; }

  // Takes a snapshot of the current scenic composition and dumps it to
  // std::out in glTF format.
  void TakeSnapshot() {
    // If we wait for a call back from GetDisplayInfo, we are guaranteed that
    // the GFX system is initialized, which is a prerequisite for taking a
    // screenshot. TODO(SCN-678): Remove call to GetDisplayInfo once bug done.
    scenic_->GetDisplayInfo([this](fuchsia::ui::gfx::DisplayInfo /*unused*/) {
      view_snapshot_->TakeSnapshot(0, [this](fuchsia::mem::Buffer buffer) {
        std::vector<uint8_t> data;
        if (!fsl::VectorFromVmo(buffer, &data)) {
          FXL_LOG(ERROR) << "TakeSnapshot failed";
          encountered_error_ = true;
          loop_->Quit();
          return;
        }

        // We currently support flatbuffer.v1_0 format.
        auto snapshot = (const SnapshotData *)data.data();
        if (snapshot->type != SnapshotData::SnapshotType::kFlatBuffer ||
            snapshot->version != SnapshotData::SnapshotVersion::v1_0) {
          FXL_LOG(ERROR) << "Invalid snapshot format encountered. Aborting.";
          encountered_error_ = true;
          loop_->Quit();
          return;
        }

        // De-serialize the snapshot from flatbuffer.
        auto node = flatbuffers::GetRoot<snapshot::Node>(snapshot->data);

        // Start with an empty glTF document.
        document_.Parse(EMPTY_GLTF_DOC);

        // Export root node of the scene graph. This recursively exports all
        // descendant nodes.
        int index = glTF_export_node(node, true);
        auto &gltf_nodes = document_["scenes"][0]["nodes"];
        gltf_nodes.PushBack(index, document_.GetAllocator());

        // Dump the result json document in glTF format to stdout.
        std::cout << document_;

        loop_->Quit();
      });
    });
  }

 private:
  int glTF_export_node(const snapshot::Node *node, bool flip_yaxis = false) {
    // The allocator used through out.
    auto &allocator = document_.GetAllocator();

    auto gltf_node = Value(kObjectType);
    if (node->name()) {
      gltf_node.AddMember("name", node->name()->str(), allocator);
    }

    if (node->transform()) {
      auto translation = node->transform()->translation();
      if (translation->x() != 0.0 || translation->y() != 0.0 ||
          translation->z() != 0.0) {
        auto gltf_translation = Value(kArrayType);
        gltf_translation.PushBack(translation->x(), allocator);
        gltf_translation.PushBack(translation->y(), allocator);
        gltf_translation.PushBack(translation->z(), allocator);
        gltf_node.AddMember("translation", gltf_translation, allocator);
      }

      auto rotation = node->transform()->rotation();
      if (rotation->x() != 0.0 || rotation->y() != 0.0 ||
          rotation->z() != 0.0 || rotation->w() != 1.0) {
        auto gltf_rotation = Value(kArrayType);
        gltf_rotation.PushBack(rotation->x(), allocator);
        gltf_rotation.PushBack(rotation->y(), allocator);
        gltf_rotation.PushBack(rotation->z(), allocator);
        gltf_rotation.PushBack(rotation->w(), allocator);
        gltf_node.AddMember("rotation", gltf_rotation, allocator);
      }

      auto scale = node->transform()->scale();
      if (scale->x() != 1.0 || scale->y() != 1.0 || scale->z() != 1.0) {
        auto gltf_scale = Value(kArrayType);
        gltf_scale.PushBack(scale->x(), allocator);
        if (flip_yaxis) {
          gltf_scale.PushBack(scale->y() * -1, allocator);
        } else {
          gltf_scale.PushBack(scale->y(), allocator);
        }
        gltf_scale.PushBack(scale->z(), allocator);
        gltf_node.AddMember("scale", gltf_scale, allocator);
      }
    }

    if (node->mesh()) {
      int index = glTF_export_mesh(node);
      gltf_node.AddMember("mesh", index, allocator);
    }

    auto &gltf_nodes = document_["nodes"];
    auto index = gltf_nodes.Size();
    gltf_nodes.PushBack(gltf_node, allocator);

    if (node->children()) {
      auto child_nodes = Value(kArrayType);
      for (auto child : *node->children()) {
        int index = glTF_export_node(child);
        child_nodes.PushBack(index, allocator);
      }
      auto &gltf_node = document_["nodes"][index];
      gltf_node.AddMember("children", child_nodes, allocator);
    }
    return index;
  }

  int glTF_export_mesh(const snapshot::Node *node) {
    // The allocator used through out.
    auto &allocator = document_.GetAllocator();

    auto gltf_primitive = Value(kObjectType);
    gltf_primitive.AddMember("material", glTF_export_material(node), allocator);
    gltf_primitive.AddMember("attributes",
                             glTF_export_buffer(node->mesh(), true), allocator);
    gltf_primitive.AddMember("indices", glTF_export_buffer(node->mesh(), false),
                             allocator);

    auto gltf_primitives = Value(kArrayType);
    gltf_primitives.PushBack(gltf_primitive, allocator);

    auto gltf_mesh = Value(kObjectType);
    gltf_mesh.AddMember("primitives", gltf_primitives, allocator);

    auto &gltf_meshes = document_["meshes"];
    auto index = gltf_meshes.Size();
    gltf_meshes.PushBack(gltf_mesh, allocator);

    return index;
  }

  Value glTF_export_buffer(const snapshot::Geometry *mesh,
                           bool is_vertex_buffer) {
    auto &allocator = document_.GetAllocator();

    const uint8_t *bytes = is_vertex_buffer
                               ? mesh->attributes()->Get(0)->buffer()->Data()
                               : mesh->indices()->buffer()->Data();
    size_t size = is_vertex_buffer
                      ? mesh->attributes()->Get(0)->buffer()->Length()
                      : mesh->indices()->buffer()->Length();
    int count = is_vertex_buffer ? mesh->attributes()->Get(0)->vertex_count()
                                 : mesh->indices()->index_count();

    // Create a glTF buffer.
    std::string base64_bytes;
    Base64Encode(bytes, size, &base64_bytes);
    std::ostringstream data;
    data << "data:application/octet-stream;base64," << base64_bytes;

    auto data_str = data.str();
    Value data_uri(kStringType);
    data_uri.SetString(data_str.c_str(), data_str.length(), allocator);

    Value gltf_buffer(kObjectType);
    gltf_buffer.AddMember("uri", data_uri, allocator);
    gltf_buffer.AddMember("byteLength", size, allocator);

    auto &gltf_buffers = document_["buffers"];
    int buffer_index = gltf_buffers.Size();
    gltf_buffers.PushBack(gltf_buffer, allocator);

    // Create a glTF bufferView.
    Value gltf_bufferView(kObjectType);
    gltf_bufferView.AddMember("buffer", Value(buffer_index), allocator);
    gltf_bufferView.AddMember("byteOffset", Value(0), allocator);
    gltf_bufferView.AddMember("byteLength", size, allocator);
    gltf_bufferView.AddMember(
        "target", is_vertex_buffer ? Value(34962) : Value(34963), allocator);
    if (is_vertex_buffer) {
      gltf_bufferView.AddMember(
          "byteStride", mesh->attributes()->Get(0)->stride(), allocator);
    }

    auto &gltf_bufferViews = document_["bufferViews"];
    int buffer_view_index = gltf_bufferViews.Size();
    gltf_bufferViews.PushBack(gltf_bufferView, allocator);

    // Create a glTF accessor.
    Value gltf_accessor(kObjectType);
    gltf_accessor.AddMember("bufferView", Value(buffer_view_index), allocator);
    gltf_accessor.AddMember("byteOffset", Value(0), allocator);
    gltf_accessor.AddMember("componentType",
                            is_vertex_buffer ? Value(5126) : Value(5125),
                            allocator);
    gltf_accessor.AddMember("count", count, allocator);
    gltf_accessor.AddMember(
        "type", is_vertex_buffer ? Value("VEC3") : Value("SCALAR"), allocator);
    if (is_vertex_buffer) {
      Value gltf_max(kArrayType);
      gltf_max.PushBack(mesh->bbox_max()->x(), allocator);
      gltf_max.PushBack(mesh->bbox_max()->y(), allocator);
      gltf_max.PushBack(mesh->bbox_max()->z(), allocator);

      Value gltf_min(kArrayType);
      gltf_min.PushBack(mesh->bbox_min()->x(), allocator);
      gltf_min.PushBack(mesh->bbox_min()->y(), allocator);
      gltf_min.PushBack(mesh->bbox_min()->z(), allocator);

      gltf_accessor.AddMember("max", gltf_max, allocator);
      gltf_accessor.AddMember("min", gltf_min, allocator);
    }

    auto &gltf_accessors = document_["accessors"];
    int accessor_index = gltf_accessors.Size();
    gltf_accessors.PushBack(gltf_accessor, allocator);

    int texture_accessor_index = gltf_accessors.Size();

    // Add texture accessor for vertex buffer.
    if (is_vertex_buffer) {
      Value gltf_accessor(kObjectType);
      gltf_accessor.AddMember("bufferView", Value(buffer_view_index),
                              allocator);
      gltf_accessor.AddMember("byteOffset", Value(8), allocator);
      gltf_accessor.AddMember("componentType", Value(5126), allocator);
      gltf_accessor.AddMember("count", count, allocator);
      gltf_accessor.AddMember("type", Value("VEC2"), allocator);

      Value gltf_max(kArrayType);
      gltf_max.PushBack(1.0, allocator);
      gltf_max.PushBack(1.0, allocator);

      Value gltf_min(kArrayType);
      gltf_min.PushBack(0.0, allocator);
      gltf_min.PushBack(0.0, allocator);

      gltf_accessor.AddMember("max", gltf_max, allocator);
      gltf_accessor.AddMember("min", gltf_min, allocator);

      gltf_accessors.PushBack(gltf_accessor, allocator);
    }

    // Add the accessor index to the glTF primitive.
    if (is_vertex_buffer) {
      auto gltf_attributes = Value(kObjectType);
      gltf_attributes.AddMember("POSITION", accessor_index, allocator);
      gltf_attributes.AddMember("TEXCOORD_0", texture_accessor_index,
                                allocator);
      return gltf_attributes;
    } else {
      return Value(accessor_index);
    }
  }

  int glTF_export_material(const snapshot::Node *node) {
    auto &allocator = document_.GetAllocator();
    if (node->material_type() == snapshot::Material_Color) {
      auto color = static_cast<const snapshot::Color *>(node->material());
      Document gltf_material(kObjectType, &allocator);
      gltf_material.Parse(EMPTY_COLOR_MATERIAL);
      auto &gltf_color =
          gltf_material["pbrMetallicRoughness"]["baseColorFactor"];
      gltf_color.Clear();
      gltf_color.PushBack(color->red(), allocator);
      gltf_color.PushBack(color->green(), allocator);
      gltf_color.PushBack(color->blue(), allocator);
      gltf_color.PushBack(color->alpha(), allocator);

      auto &gltf_materials = document_["materials"];
      int materials_index = gltf_materials.Size();
      gltf_materials.PushBack(gltf_material, allocator);
      return materials_index;
    } else {
      auto image = static_cast<const snapshot::Image *>(node->material());

      // Convert raw image to png.
      const uint8_t *bytes = image->data()->Data();
      std::vector<uint8_t> out;
      if (!RawToPNG(image->width(), image->height(), bytes, out)) {
        FXL_LOG(FATAL) << "Unable to convert to PNG";
        return -1;
      }
      // Encode to base64.
      std::string base64_bytes;
      Base64Encode(out.data(), out.size(), &base64_bytes);
      std::ostringstream data;
      data << "data:image/png;base64," << base64_bytes;

      auto data_str = data.str();
      Value data_uri(kStringType);
      data_uri.SetString(data_str.c_str(), data_str.length(), allocator);

      Value gltf_image(kObjectType);
      gltf_image.AddMember("mimeType", "image/png", allocator);
      gltf_image.AddMember("width", image->width(), allocator);
      gltf_image.AddMember("height", image->height(), allocator);
      gltf_image.AddMember("format", image->format(), allocator);
      gltf_image.AddMember("size", out.size(), allocator);
      gltf_image.AddMember("uri", data_uri, allocator);

      auto &gltf_images = document_["images"];
      int image_index = gltf_images.Size();
      gltf_images.PushBack(gltf_image, allocator);

      Value gltf_texture(kObjectType);
      gltf_texture.AddMember("sampler", 0, allocator);
      gltf_texture.AddMember("source", image_index, allocator);

      auto &gltf_textures = document_["textures"];
      int texture_index = gltf_textures.Size();
      gltf_textures.PushBack(gltf_texture, allocator);

      Document gltf_material(kObjectType, &allocator);
      gltf_material.Parse(EMPTY_TEXTURE_MATERIAL);
      auto &gltf_baseColorTexture =
          gltf_material["pbrMetallicRoughness"]["baseColorTexture"];
      gltf_baseColorTexture.AddMember("index", texture_index, allocator);

      auto &gltf_materials = document_["materials"];
      int materials_index = gltf_materials.Size();
      gltf_materials.PushBack(gltf_material, allocator);
      return materials_index;
    }
  }

 private:
  async::Loop *loop_;
  std::unique_ptr<component::StartupContext> context_;
  bool encountered_error_ = false;
  fuchsia::ui::scenic::ScenicPtr scenic_;
  fuchsia::ui::viewsv1::ViewSnapshotPtr view_snapshot_;
  Document document_;
};

int main(int argc, const char **argv) {
  auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  if (!fxl::SetLogSettingsFromCommandLine(command_line))
    return 1;

  const auto &positional_args = command_line.positional_args();
  if (positional_args.size() != 0) {
    FXL_LOG(ERROR)
        << "Usage: gltf_export\n"
        << "Takes a snapshot in glTF format and writes it to stdout.\n"
        << "To write to a file, redirect stdout, e.g.: "
        << "gltf_export > \"${DST}\"";
    return 1;
  }

  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  trace::TraceProvider trace_provider(loop.dispatcher());

  SnapshotTaker taker(&loop);
  taker.TakeSnapshot();
  loop.Run();

  return taker.encountered_error() ? EXIT_FAILURE : EXIT_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////
// PNG encode.

bool RawToPNG(size_t width, size_t height, const uint8_t *data,
              std::vector<uint8_t> &out) {
  out.clear();

  png_structp png_ptr =
      png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  png_infop info_ptr = png_create_info_struct(png_ptr);

  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_write_struct(&png_ptr, NULL);
    FXL_LOG(ERROR) << "Unable to create write struct";
    return false;
  }

  png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);

  std::vector<uint8_t *> rows(height);
  for (size_t y = 0; y < height; ++y) {
    rows[y] = (uint8_t *)data + y * width * 4;
  }
  png_set_rows(png_ptr, info_ptr, &rows[0]);
  png_set_write_fn(
      png_ptr, &out,
      [](png_structp png_ptr, png_bytep data, png_size_t length) {
        std::vector<uint8_t> *p =
            (std::vector<uint8_t> *)png_get_io_ptr(png_ptr);
        p->insert(p->end(), data, data + length);
      },
      NULL);
  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, NULL);

  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_write_struct(&png_ptr, NULL);
    FXL_LOG(ERROR) << "Unable to create write png";
    return false;
  }

  png_destroy_write_struct(&png_ptr, NULL);
  return true;
}
