// Copyright 2017 The Chromium 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 "chrome/browser/vr/gltf_parser.h"

#include <memory>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/json/json_file_value_serializer.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/vr/test/paths.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace vr {

// TODO(crbug/770891): Fix GLTF parsing on Windows and reenable the test.
#if defined(OS_WIN)
#define MAYBE(x) DISABLED_##x
#else
#define MAYBE(x) x
#endif

class DataDrivenTest : public testing::Test {
 protected:
  void SetUp() override { test::GetTestDataPath(&data_dir_); }

  base::FilePath data_dir_;
};

class GltfParserTest : public DataDrivenTest {
 protected:
  std::unique_ptr<base::DictionaryValue> Deserialize(
      const base::FilePath& gltf_path);
};

class BinaryGltfParserTest : public DataDrivenTest {};

std::unique_ptr<base::DictionaryValue> GltfParserTest::Deserialize(
    const base::FilePath& gltf_path) {
  int error_code;
  std::string error_msg;
  JSONFileValueDeserializer json_deserializer(gltf_path);
  auto asset_value = json_deserializer.Deserialize(&error_code, &error_msg);
  EXPECT_NE(nullptr, asset_value);
  base::DictionaryValue* asset;
  EXPECT_TRUE(asset_value->GetAsDictionary(&asset));
  asset_value.release();
  return std::unique_ptr<base::DictionaryValue>(asset);
}

TEST_F(GltfParserTest, MAYBE(Parse)) {
  auto asset =
      Deserialize(data_dir_.Append(FILE_PATH_LITERAL("sample_inline.gltf")));
  GltfParser parser;
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;

  std::unique_ptr<gltf::Asset> gltf_model = parser.Parse(*asset, &buffers);
  EXPECT_TRUE(gltf_model);
  EXPECT_EQ(1u, buffers.size());

  const gltf::Buffer* buffer = buffers[0].get();
  EXPECT_EQ("HELLO WORLD!", *buffer);
  EXPECT_EQ(12u, buffer->length());

  const gltf::BufferView* buffer_view = gltf_model->GetBufferView(0);
  EXPECT_NE(nullptr, buffer_view);
  EXPECT_EQ(nullptr, gltf_model->GetBufferView(1));
  EXPECT_EQ(0, buffer_view->buffer);
  EXPECT_EQ(20, buffer_view->byte_length);
  EXPECT_EQ(10, buffer_view->byte_offset);
  EXPECT_EQ(1, buffer_view->target);

  const gltf::Accessor* accessor = gltf_model->GetAccessor(0);
  EXPECT_NE(nullptr, accessor);
  EXPECT_EQ(nullptr, gltf_model->GetAccessor(1));
  EXPECT_EQ(buffer_view, accessor->buffer_view);
  EXPECT_EQ(10, accessor->byte_offset);
  EXPECT_EQ(16, accessor->byte_stride);
  EXPECT_EQ(5, accessor->component_type);
  EXPECT_EQ(24, accessor->count);
  EXPECT_EQ(gltf::VEC3, accessor->type);

  const gltf::Mesh* mesh = gltf_model->GetMesh(0);
  EXPECT_NE(nullptr, mesh);
  EXPECT_EQ(nullptr, gltf_model->GetAccessor(1));
  EXPECT_EQ(1u, mesh->primitives.size());
  gltf::Mesh::Primitive* primitive = mesh->primitives[0].get();
  EXPECT_EQ(1u, primitive->attributes.size());
  auto attr_it = primitive->attributes.begin();
  EXPECT_EQ("POSITION", attr_it->first);
  EXPECT_EQ(accessor, attr_it->second);
  EXPECT_EQ(accessor, primitive->indices);
  EXPECT_EQ(4, primitive->mode);

  const gltf::Node* node_1 = gltf_model->GetNode(0);
  const gltf::Node* node_2 = gltf_model->GetNode(1);
  EXPECT_NE(nullptr, node_1);
  EXPECT_NE(nullptr, node_2);
  EXPECT_EQ(nullptr, gltf_model->GetNode(2));
  EXPECT_EQ(1u, node_1->children.size());
  EXPECT_EQ(0u, node_1->meshes.size());
  EXPECT_EQ(node_2, node_1->children[0]);
  EXPECT_EQ(0u, node_2->children.size());
  EXPECT_EQ(1u, node_2->meshes.size());
  EXPECT_EQ(mesh, node_2->meshes[0]);

  const gltf::Scene* scene = gltf_model->GetScene(0);
  EXPECT_NE(nullptr, scene);
  EXPECT_EQ(nullptr, gltf_model->GetNode(2));
  EXPECT_EQ(1u, scene->nodes.size());
  EXPECT_EQ(node_1, scene->nodes[0]);

  EXPECT_EQ(scene, gltf_model->GetMainScene());
}

TEST_F(GltfParserTest, MAYBE(ParseUnknownBuffer)) {
  auto asset =
      Deserialize(data_dir_.Append(FILE_PATH_LITERAL("sample_inline.gltf")));
  GltfParser parser;
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;

  // Parsing succeeds.
  EXPECT_NE(nullptr, parser.Parse(*asset, &buffers));

  // Parsing fails when a referenced buffer is removed.
  std::unique_ptr<base::Value> value;
  asset->Remove("buffers.dummyBuffer", &value);
  EXPECT_EQ(nullptr, parser.Parse(*asset, &buffers));

  // Parsing fails when the buffer is reinserted with a different ID.
  asset->Set("buffers.anotherDummyBuffer", std::move(value));
  EXPECT_EQ(nullptr, parser.Parse(*asset, &buffers));
}

TEST_F(GltfParserTest, MAYBE(ParseMissingRequired)) {
  auto asset =
      Deserialize(data_dir_.Append(FILE_PATH_LITERAL("sample_inline.gltf")));
  GltfParser parser;
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;

  std::unique_ptr<base::Value> value;
  asset->Remove("buffers.dummyBuffer.uri", &value);
  EXPECT_EQ(nullptr, parser.Parse(*asset, &buffers));
}

TEST_F(GltfParserTest, MAYBE(ParseExternal)) {
  auto gltf_path = data_dir_.Append(FILE_PATH_LITERAL("sample_external.gltf"));
  GltfParser parser;
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;

  std::unique_ptr<gltf::Asset> gltf_model = parser.Parse(gltf_path, &buffers);
  EXPECT_NE(nullptr, gltf_model);
  EXPECT_EQ(1u, buffers.size());
  const gltf::Buffer* buffer = buffers[0].get();
  EXPECT_NE(nullptr, buffer);
  EXPECT_EQ("HELLO WORLD!", *buffer);
  EXPECT_EQ(12u, buffer->length());
}

TEST_F(GltfParserTest, MAYBE(ParseExternalNoPath)) {
  auto asset =
      Deserialize(data_dir_.Append(FILE_PATH_LITERAL("sample_external.gltf")));
  GltfParser parser;
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;

  // Parsing fails when no path is provided.
  EXPECT_EQ(nullptr, parser.Parse(*asset, &buffers));
}

TEST_F(BinaryGltfParserTest, MAYBE(ParseBinary)) {
  std::string data;
  EXPECT_TRUE(base::ReadFileToString(
      data_dir_.Append(FILE_PATH_LITERAL("sample.glb")), &data));
  base::StringPiece glb_data(data);
  std::vector<std::unique_ptr<gltf::Buffer>> buffers;
  std::unique_ptr<gltf::Asset> asset =
      BinaryGltfParser::Parse(glb_data, &buffers);
  EXPECT_TRUE(asset);
  EXPECT_EQ(1u, buffers.size());
  const gltf::BufferView* buffer_view = asset->GetBufferView(0);
  EXPECT_TRUE(buffer_view);
  EXPECT_EQ(0, buffer_view->buffer);
}

}  // namespace vr
