// 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/playground/playground_test.h"
#include "impeller/typographer/backends/skia/text_frame_skia.h"
#include "impeller/typographer/backends/skia/text_render_context_skia.h"
#include "impeller/typographer/lazy_glyph_atlas.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkFontMgr.h"
#include "third_party/skia/include/core/SkTextBlob.h"

// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
// NOLINTBEGIN(bugprone-unchecked-optional-access)

namespace impeller {
namespace testing {

using TypographerTest = PlaygroundTest;
INSTANTIATE_PLAYGROUND_SUITE(TypographerTest);

TEST_P(TypographerTest, CanConvertTextBlob) {
  SkFont font;
  auto blob = SkTextBlob::MakeFromString(
      "the quick brown fox jumped over the lazy dog.", font);
  ASSERT_TRUE(blob);
  auto frame = TextFrameFromTextBlob(blob);
  ASSERT_EQ(frame.GetRunCount(), 1u);
  for (const auto& run : frame.GetRuns()) {
    ASSERT_TRUE(run.IsValid());
    ASSERT_EQ(run.GetGlyphCount(), 45u);
  }
}

TEST_P(TypographerTest, CanCreateRenderContext) {
  auto context = TextRenderContext::Create(GetContext());
  ASSERT_TRUE(context && context->IsValid());
}

TEST_P(TypographerTest, CanCreateGlyphAtlas) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;
  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
  ASSERT_TRUE(blob);
  auto atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);
  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);

  std::optional<FontGlyphPair> first_pair;
  Rect first_rect;
  atlas->IterateGlyphs(
      [&](const FontGlyphPair& pair, const Rect& rect) -> bool {
        first_pair = pair;
        first_rect = rect;
        return false;
      });

  ASSERT_TRUE(first_pair.has_value());
  ASSERT_TRUE(atlas->FindFontGlyphBounds(first_pair.value()).has_value());
}

static sk_sp<SkData> OpenFixtureAsSkData(const char* fixture_name) {
  auto mapping = flutter::testing::OpenFixtureAsMapping(fixture_name);
  if (!mapping) {
    return nullptr;
  }
  auto data = SkData::MakeWithProc(
      mapping->GetMapping(), mapping->GetSize(),
      [](const void* ptr, void* context) {
        delete reinterpret_cast<fml::Mapping*>(context);
      },
      mapping.get());
  mapping.release();
  return data;
}

TEST_P(TypographerTest, LazyAtlasTracksColor) {
#if FML_OS_MACOSX
  auto mapping = OpenFixtureAsSkData("Apple Color Emoji.ttc");
#else
  auto mapping = OpenFixtureAsSkData("NotoColorEmoji.ttf");
#endif
  ASSERT_TRUE(mapping);
  SkFont emoji_font(SkTypeface::MakeFromData(mapping), 50.0);
  SkFont sk_font;

  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
  ASSERT_TRUE(blob);
  auto frame = TextFrameFromTextBlob(blob);

  ASSERT_FALSE(frame.GetAtlasType() == GlyphAtlas::Type::kColorBitmap);

  LazyGlyphAtlas lazy_atlas;

  lazy_atlas.AddTextFrame(frame);

  frame = TextFrameFromTextBlob(SkTextBlob::MakeFromString("😀 ", emoji_font));

  ASSERT_TRUE(frame.GetAtlasType() == GlyphAtlas::Type::kColorBitmap);

  lazy_atlas.AddTextFrame(frame);

  // Creates different atlases for color and alpha bitmap.
  auto color_context = std::make_shared<GlyphAtlasContext>();
  auto bitmap_context = std::make_shared<GlyphAtlasContext>();
  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
      GlyphAtlas::Type::kColorBitmap, color_context, GetContext());

  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
      GlyphAtlas::Type::kAlphaBitmap, bitmap_context, GetContext());

  ASSERT_FALSE(color_atlas == bitmap_atlas);
}

TEST_P(TypographerTest, GlyphAtlasWithOddUniqueGlyphSize) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;
  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
  ASSERT_TRUE(blob);
  auto atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);

  ASSERT_EQ(atlas->GetTexture()->GetSize().width,
            atlas->GetTexture()->GetSize().height);
}

TEST_P(TypographerTest, GlyphAtlasIsRecycledIfUnchanged) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;
  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
  ASSERT_TRUE(blob);
  auto atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);
  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());

  // now attempt to re-create an atlas with the same text blob.

  auto next_atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  ASSERT_EQ(atlas, next_atlas);
  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
}

TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;

  const char* test_string =
      "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
      "2134567890-=!@#$%^&*()_+"
      "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›ﬁﬂ‡°·‚—±Œ„´‰Á¨Ø∏”’/"
      "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";

  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
  ASSERT_TRUE(blob);

  TextFrame frame;
  size_t count = 0;
  const int size_count = 8;
  TextRenderContext::FrameIterator iterator = [&]() -> const TextFrame* {
    if (count < size_count) {
      count++;
      frame = TextFrameFromTextBlob(blob, 0.6 * count);
      return &frame;
    }
    return nullptr;
  };
  auto atlas = context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap,
                                         atlas_context, iterator);
  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);

  std::set<uint16_t> unique_glyphs;
  std::vector<uint16_t> total_glyphs;
  atlas->IterateGlyphs([&](const FontGlyphPair& pair, const Rect& rect) {
    unique_glyphs.insert(pair.glyph.index);
    total_glyphs.push_back(pair.glyph.index);
    return true;
  });

  EXPECT_EQ(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());

  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
}

TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;
  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
  ASSERT_TRUE(blob);
  auto atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  auto old_packer = atlas_context->GetRectPacker();

  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);
  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());

  auto* first_texture = atlas->GetTexture().get();

  // Now create a new glyph atlas with a nearly identical blob.

  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
  auto next_atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob2));
  ASSERT_EQ(atlas, next_atlas);
  auto* second_texture = next_atlas->GetTexture().get();

  auto new_packer = atlas_context->GetRectPacker();

  ASSERT_EQ(second_texture, first_texture);
  ASSERT_EQ(old_packer, new_packer);
}

TEST_P(TypographerTest, GlyphAtlasTextureIsRecreatedIfTypeChanges) {
  auto context = TextRenderContext::Create(GetContext());
  auto atlas_context = std::make_shared<GlyphAtlasContext>();
  ASSERT_TRUE(context && context->IsValid());
  SkFont sk_font;
  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
  ASSERT_TRUE(blob);
  auto atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kAlphaBitmap, atlas_context,
                                TextFrameFromTextBlob(blob));
  auto old_packer = atlas_context->GetRectPacker();

  ASSERT_NE(atlas, nullptr);
  ASSERT_NE(atlas->GetTexture(), nullptr);
  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());

  auto* first_texture = atlas->GetTexture().get();

  // now create a new glyph atlas with an identical blob,
  // but change the type.

  auto blob2 = SkTextBlob::MakeFromString("spooky 1", sk_font);
  auto next_atlas =
      context->CreateGlyphAtlas(GlyphAtlas::Type::kColorBitmap, atlas_context,
                                TextFrameFromTextBlob(blob2));
  ASSERT_NE(atlas, next_atlas);
  auto* second_texture = next_atlas->GetTexture().get();

  auto new_packer = atlas_context->GetRectPacker();

  ASSERT_NE(second_texture, first_texture);
  ASSERT_NE(old_packer, new_packer);
}

TEST_P(TypographerTest, FontGlyphPairTypeChangesHashAndEquals) {
  Font font = Font(nullptr, {});
  FontGlyphPair pair_1 = {
      .font = font,
      .glyph = Glyph(0, Glyph::Type::kBitmap, Rect::MakeXYWH(0, 0, 1, 1))};
  // Same glyph same type.
  FontGlyphPair pair_2 = {
      .font = font,
      .glyph = Glyph(0, Glyph::Type::kBitmap, Rect::MakeXYWH(0, 0, 1, 1))};
  // Same glyph different type.
  FontGlyphPair pair_3 = {
      .font = font,
      .glyph = Glyph(0, Glyph::Type::kPath, Rect::MakeXYWH(0, 0, 1, 1))};

  ASSERT_TRUE(FontGlyphPair::Equal{}(pair_1, pair_2));
  ASSERT_FALSE(FontGlyphPair::Equal{}(pair_1, pair_3));
}

TEST_P(TypographerTest, MaybeHasOverlapping) {
  sk_sp<SkFontMgr> font_mgr = SkFontMgr::RefDefault();
  sk_sp<SkTypeface> typeface =
      font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
  SkFont sk_font(typeface, 0.5f);

  auto frame = TextFrameFromTextBlob(SkTextBlob::MakeFromString("1", sk_font));
  // Single character has no overlapping
  ASSERT_FALSE(frame.MaybeHasOverlapping());

  auto frame_2 =
      TextFrameFromTextBlob(SkTextBlob::MakeFromString("123456789", sk_font));
  // Characters probably have overlap due to low fidelity text metrics, but this
  // could be fixed.
  ASSERT_TRUE(frame_2.MaybeHasOverlapping());
}

}  // namespace testing
}  // namespace impeller

// NOLINTEND(bugprone-unchecked-optional-access)
