/*
 * 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++;
  }
}
