// 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 "gtest/gtest.h"
#include "impeller/geometry/path.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/tessellator/tessellator.h"

namespace impeller {
namespace testing {

TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
  // Zero points.
  {
    Tessellator t;
    auto path = PathBuilder{}.TakePath(FillType::kPositive);
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [](const float* vertices, size_t vertices_count,
           const uint16_t* indices, size_t indices_count) { return true; });

    ASSERT_EQ(result, Tessellator::Result::kInputError);
  }

  // One point.
  {
    Tessellator t;
    auto path = PathBuilder{}.LineTo({0, 0}).TakePath(FillType::kPositive);
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [](const float* vertices, size_t vertices_count,
           const uint16_t* indices, size_t indices_count) { return true; });

    ASSERT_EQ(result, Tessellator::Result::kSuccess);
  }

  // Two points.
  {
    Tessellator t;
    auto path =
        PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [](const float* vertices, size_t vertices_count,
           const uint16_t* indices, size_t indices_count) { return true; });

    ASSERT_EQ(result, Tessellator::Result::kSuccess);
  }

  // Many points.
  {
    Tessellator t;
    PathBuilder builder;
    for (int i = 0; i < 1000; i++) {
      auto coord = i * 1.0f;
      builder.AddLine({coord, coord}, {coord + 1, coord + 1});
    }
    auto path = builder.TakePath(FillType::kPositive);
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [](const float* vertices, size_t vertices_count,
           const uint16_t* indices, size_t indices_count) { return true; });

    ASSERT_EQ(result, Tessellator::Result::kSuccess);
  }

  // Closure fails.
  {
    Tessellator t;
    auto path =
        PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kPositive);
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [](const float* vertices, size_t vertices_count,
           const uint16_t* indices, size_t indices_count) { return false; });

    ASSERT_EQ(result, Tessellator::Result::kInputError);
  }

  // More than 30 contours, non-zero fill mode.
  {
    Tessellator t;
    PathBuilder builder = {};
    for (auto i = 0u; i < Tessellator::kMultiContourThreshold + 1; i++) {
      builder.AddCircle(Point(i, i), 4);
    }
    auto path = builder.TakePath(FillType::kNonZero);
    bool no_indices = false;
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [&no_indices](const float* vertices, size_t vertices_count,
                      const uint16_t* indices, size_t indices_count) {
          no_indices = indices == nullptr;
          return true;
        });

    ASSERT_TRUE(no_indices);
    ASSERT_EQ(result, Tessellator::Result::kSuccess);
  }

  // More than uint16 points, odd fill mode.
  {
    Tessellator t;
    PathBuilder builder = {};
    for (auto i = 0; i < 1000; i++) {
      builder.AddCircle(Point(i, i), 4);
    }
    auto path = builder.TakePath(FillType::kOdd);
    bool no_indices = false;
    size_t count = 0u;
    Tessellator::Result result = t.Tessellate(
        path, 1.0f,
        [&no_indices, &count](const float* vertices, size_t vertices_count,
                              const uint16_t* indices, size_t indices_count) {
          no_indices = indices == nullptr;
          count = vertices_count;
          return true;
        });

    ASSERT_TRUE(no_indices);
    ASSERT_TRUE(count >= USHRT_MAX);
    ASSERT_EQ(result, Tessellator::Result::kSuccess);
  }
}

TEST(TessellatorTest, TessellateConvex) {
  {
    Tessellator t;
    // Sanity check simple rectangle.
    auto pts = t.TessellateConvex(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), 1.0);

    std::vector<Point> expected = {
        {0, 0}, {10, 0}, {0, 10}, {10, 10},  //
    };
    EXPECT_EQ(pts, expected);
  }

  {
    Tessellator t;
    auto pts = t.TessellateConvex(PathBuilder{}
                                      .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
                                      .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
                                      .TakePath(),
                                  1.0);

    std::vector<Point> expected = {{0, 0},   {10, 0},  {0, 10},  {10, 10},
                                   {10, 10}, {20, 20}, {20, 20}, {30, 20},
                                   {20, 30}, {30, 30}};
    EXPECT_EQ(pts, expected);
  }
}

}  // namespace testing
}  // namespace impeller
