// 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 "flutter/testing/testing.h"
#include "impeller/geometry/geometry_unittests.h"
#include "impeller/geometry/matrix.h"
#include "impeller/scene/importer/conversions.h"
#include "impeller/scene/importer/importer.h"
#include "impeller/scene/importer/scene_flatbuffers.h"

namespace impeller {
namespace scene {
namespace importer {
namespace testing {

TEST(ImporterTest, CanParseUnskinnedGLTF) {
  auto mapping =
      flutter::testing::OpenFixtureAsMapping("flutter_logo_baked.glb");

  fb::SceneT scene;
  ASSERT_TRUE(ParseGLTF(*mapping, scene));

  ASSERT_EQ(scene.children.size(), 1u);
  auto& node = scene.nodes[scene.children[0]];

  Matrix node_transform = ToMatrix(*node->transform);
  ASSERT_MATRIX_NEAR(node_transform, Matrix());

  ASSERT_EQ(node->mesh_primitives.size(), 1u);
  auto& mesh = *node->mesh_primitives[0];
  ASSERT_EQ(mesh.indices->count, 918u);

  uint16_t first_index =
      *reinterpret_cast<uint16_t*>(mesh.indices->data.data());
  ASSERT_EQ(first_index, 45u);

  ASSERT_EQ(mesh.vertices.type, fb::VertexBuffer::UnskinnedVertexBuffer);
  auto& vertices = mesh.vertices.AsUnskinnedVertexBuffer()->vertices;
  ASSERT_EQ(vertices.size(), 260u);
  auto& vertex = vertices[0];

  Vector3 position = ToVector3(vertex.position());
  ASSERT_VECTOR3_NEAR(position, Vector3(-0.0100185, -0.522907, -0.133178));

  Vector3 normal = ToVector3(vertex.normal());
  ASSERT_VECTOR3_NEAR(normal, Vector3(0.556997, -0.810833, 0.179733));

  Vector4 tangent = ToVector4(vertex.tangent());
  ASSERT_VECTOR4_NEAR(tangent, Vector4(0.155901, -0.110485, -0.981574, 1));

  Vector2 texture_coords = ToVector2(vertex.texture_coords());
  ASSERT_POINT_NEAR(texture_coords, Vector2(0.727937, 0.713817));

  Color color = ToColor(vertex.color());
  ASSERT_COLOR_NEAR(color, Color(0.0221714, 0.467781, 0.921584, 1));
}

TEST(ImporterTest, CanParseSkinnedGLTF) {
  auto mapping = flutter::testing::OpenFixtureAsMapping("two_triangles.glb");

  fb::SceneT scene;
  ASSERT_TRUE(ParseGLTF(*mapping, scene));

  ASSERT_EQ(scene.children.size(), 1u);
  auto& node = scene.nodes[scene.children[0]];

  Matrix node_transform = ToMatrix(*node->transform);
  ASSERT_MATRIX_NEAR(node_transform, Matrix());

  ASSERT_EQ(node->mesh_primitives.size(), 0u);
  ASSERT_EQ(node->children.size(), 2u);

  // The skinned node contains both a skeleton and skinned mesh primitives that
  // reference bones in the skeleton.
  auto& skinned_node = scene.nodes[node->children[0]];
  ASSERT_NE(skinned_node->skin, nullptr);

  ASSERT_EQ(skinned_node->mesh_primitives.size(), 2u);
  auto& bottom_triangle = *skinned_node->mesh_primitives[0];
  ASSERT_EQ(bottom_triangle.indices->count, 3u);

  ASSERT_EQ(bottom_triangle.vertices.type,
            fb::VertexBuffer::SkinnedVertexBuffer);
  auto& vertices = bottom_triangle.vertices.AsSkinnedVertexBuffer()->vertices;
  ASSERT_EQ(vertices.size(), 3u);
  auto& vertex = vertices[0];

  Vector3 position = ToVector3(vertex.vertex().position());
  ASSERT_VECTOR3_NEAR(position, Vector3(1, 1, 0));

  Vector3 normal = ToVector3(vertex.vertex().normal());
  ASSERT_VECTOR3_NEAR(normal, Vector3(0, 0, 1));

  Vector4 tangent = ToVector4(vertex.vertex().tangent());
  ASSERT_VECTOR4_NEAR(tangent, Vector4(1, 0, 0, -1));

  Vector2 texture_coords = ToVector2(vertex.vertex().texture_coords());
  ASSERT_POINT_NEAR(texture_coords, Vector2(0, 1));

  Color color = ToColor(vertex.vertex().color());
  ASSERT_COLOR_NEAR(color, Color(1, 1, 1, 1));

  Vector4 joints = ToVector4(vertex.joints());
  ASSERT_COLOR_NEAR(joints, Vector4(0, 0, 0, 0));

  Vector4 weights = ToVector4(vertex.weights());
  ASSERT_COLOR_NEAR(weights, Vector4(1, 0, 0, 0));

  ASSERT_EQ(scene.animations.size(), 2u);
  ASSERT_EQ(scene.animations[0]->name, "Idle");
  ASSERT_EQ(scene.animations[1]->name, "Metronome");
  ASSERT_EQ(scene.animations[1]->channels.size(), 6u);
  auto& channel = scene.animations[1]->channels[4];
  ASSERT_EQ(channel->keyframes.type, fb::Keyframes::RotationKeyframes);
  auto* keyframes = channel->keyframes.AsRotationKeyframes();
  ASSERT_EQ(keyframes->values.size(), 40u);
  ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[0]),
                      Vector4(0.653281, 0.270598, -0.270598, 0.653281));
  ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[10]),
                      Vector4(0.425122, 0.565041, -0.565041, 0.425122));
}

}  // namespace testing
}  // namespace importer
}  // namespace scene
}  // namespace impeller
