/*
 * Copyright 2017 Google, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>

#include "flutter/fml/command_line.h"
#include "flutter/fml/logging.h"
#include "flutter/third_party/txt/tests/txt_test_utils.h"
#include "third_party/benchmark/include/benchmark/benchmark_api.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/modules/skparagraph/include/Paragraph.h"
#include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h"
#include "third_party/skia/modules/skparagraph/include/TypefaceFontProvider.h"
#include "third_party/skia/modules/skparagraph/utils/TestFontCollection.h"

namespace sktxt = skia::textlayout;

class SkParagraphFixture : public benchmark::Fixture {
 public:
  void SetUp(const ::benchmark::State& state) {
    font_collection_ = sk_make_sp<sktxt::TestFontCollection>(txt::GetFontDir());

    bitmap_ = std::make_unique<SkBitmap>();
    bitmap_->allocN32Pixels(1000, 1000);
    canvas_ = std::make_unique<SkCanvas>(*bitmap_);
    canvas_->clear(SK_ColorWHITE);
  }

 protected:
  sk_sp<sktxt::TestFontCollection> font_collection_;
  std::unique_ptr<SkCanvas> canvas_;
  std::unique_ptr<SkBitmap> bitmap_;
};

BENCHMARK_F(SkParagraphFixture, ShortLayout)(benchmark::State& state) {
  const char* text = "Hello World";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(text);
  builder->pop();
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
}

BENCHMARK_F(SkParagraphFixture, LongLayout)(benchmark::State& state) {
  const char* text =
      "This is a very long sentence to test if the text will properly wrap "
      "around and go to the next line. Sometimes, short sentence. Longer "
      "sentences are okay too because they are necessary. Very short. "
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
      "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
      "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
      "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
      "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
      "mollit anim id est laborum. "
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
      "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
      "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
      "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
      "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
      "mollit anim id est laborum.";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(text);
  builder->pop();
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
}

BENCHMARK_F(SkParagraphFixture, JustifyLayout)(benchmark::State& state) {
  const char* text =
      "This is a very long sentence to test if the text will properly wrap "
      "around and go to the next line. Sometimes, short sentence. Longer "
      "sentences are okay too because they are necessary. Very short. "
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
      "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
      "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
      "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
      "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
      "mollit anim id est laborum. "
      "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod "
      "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim "
      "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
      "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate "
      "velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint "
      "occaecat cupidatat non proident, sunt in culpa qui officia deserunt "
      "mollit anim id est laborum.";
  sktxt::ParagraphStyle paragraph_style;
  paragraph_style.setTextAlign(sktxt::TextAlign::kJustify);
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(text);
  builder->pop();
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
}

BENCHMARK_F(SkParagraphFixture, ManyStylesLayout)(benchmark::State& state) {
  const char* text = "-";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  for (int i = 0; i < 1000; ++i) {
    builder->pushStyle(text_style);
    builder->addText(text);
  }
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
}

BENCHMARK_DEFINE_F(SkParagraphFixture, TextBigO)(benchmark::State& state) {
  std::vector<uint16_t> text;
  for (uint16_t i = 0; i < state.range(0); ++i) {
    text.push_back(i % 5 == 0 ? ' ' : i);
  }
  std::u16string u16_text(text.data(), text.data() + text.size());
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(u16_text);
  builder->pop();
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
  state.SetComplexityN(state.range(0));
}
BENCHMARK_REGISTER_F(SkParagraphFixture, TextBigO)
    ->RangeMultiplier(4)
    ->Range(1 << 6, 1 << 14)
    ->Complexity(benchmark::oN);

BENCHMARK_DEFINE_F(SkParagraphFixture, StylesBigO)(benchmark::State& state) {
  const char* text = "vry shrt ";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder = sktxt::ParagraphBuilder::make(
      paragraph_style,
      sk_make_sp<sktxt::TestFontCollection>(txt::GetFontDir()));
  for (int i = 0; i < 1000; ++i) {
    builder->pushStyle(text_style);
    builder->addText(text);
  }
  auto paragraph = builder->Build();
  while (state.KeepRunning()) {
    paragraph->markDirty();
    paragraph->layout(300);
  }
  state.SetComplexityN(state.range(0));
}
BENCHMARK_REGISTER_F(SkParagraphFixture, StylesBigO)
    ->RangeMultiplier(4)
    ->Range(1 << 3, 1 << 12)
    ->Complexity(benchmark::oN);

BENCHMARK_F(SkParagraphFixture, PaintSimple)(benchmark::State& state) {
  const char* text = "This is a simple sentence to test drawing.";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(text);
  builder->pop();
  auto paragraph = builder->Build();
  paragraph->layout(300);
  int offset = 0;
  while (state.KeepRunning()) {
    paragraph->paint(canvas_.get(), offset % 700, 10);
    offset++;
  }
}

BENCHMARK_F(SkParagraphFixture, PaintLarge)(benchmark::State& state) {
  const char* text =
      "Hello world! This is a simple sentence to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.Hello world! This is a simple sentence "
      "to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.Hello world! This is a simple sentence "
      "to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.Hello world! This is a simple sentence "
      "to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.Hello world! This is a simple sentence "
      "to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.Hello world! This is a simple sentence "
      "to test drawing. Hello world! "
      "This is a simple sentence to test drawing. Hello world! This is a "
      "simple sentence to test drawing.";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  builder->pushStyle(text_style);
  builder->addText(text);
  builder->pop();
  auto paragraph = builder->Build();
  paragraph->layout(300);
  int offset = 0;
  while (state.KeepRunning()) {
    paragraph->paint(canvas_.get(), offset % 700, 10);
    offset++;
  }
}

BENCHMARK_F(SkParagraphFixture, PaintDecoration)(benchmark::State& state) {
  const char* text =
      "Hello world! This is a simple sentence to test drawing. Hello world! "
      "This is a simple sentence to test drawing.";
  sktxt::ParagraphStyle paragraph_style;
  sktxt::TextStyle text_style;
  text_style.setFontFamilies({SkString("Roboto")});
  text_style.setColor(SK_ColorBLACK);
  text_style.setDecoration(static_cast<sktxt::TextDecoration>(
      sktxt::TextDecoration::kLineThrough | sktxt::TextDecoration::kOverline |
      sktxt::TextDecoration::kUnderline));
  auto builder =
      sktxt::ParagraphBuilder::make(paragraph_style, font_collection_);
  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kSolid);
  builder->pushStyle(text_style);
  builder->addText(text);

  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kDotted);
  builder->pushStyle(text_style);
  builder->addText(text);

  text_style.setDecorationStyle(sktxt::TextDecorationStyle::kWavy);
  builder->pushStyle(text_style);
  builder->addText(text);

  auto paragraph = builder->Build();
  paragraph->layout(300);
  int offset = 0;
  while (state.KeepRunning()) {
    paragraph->paint(canvas_.get(), offset % 700, 10);
    offset++;
  }
}
