/*
 * 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 "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/SkColor.h"
#include "txt/font_collection.h"
#include "txt/font_style.h"
#include "txt/font_weight.h"
#include "txt/paragraph.h"
#include "txt/paragraph_builder_txt.h"

namespace txt {

static void BM_ParagraphBuilderConstruction(benchmark::State& state) {
  txt::ParagraphStyle paragraph_style;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
  }
}
BENCHMARK(BM_ParagraphBuilderConstruction);

static void BM_ParagraphBuilderPushStyle(benchmark::State& state) {
  txt::ParagraphStyle paragraph_style;

  txt::TextStyle text_style;
  text_style.color = SK_ColorBLACK;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.PushStyle(text_style);
  }
}
BENCHMARK(BM_ParagraphBuilderPushStyle);

static void BM_ParagraphBuilderPushPop(benchmark::State& state) {
  txt::ParagraphStyle paragraph_style;
  txt::ParagraphBuilderTxt builder(paragraph_style, GetTestFontCollection());

  txt::TextStyle text_style;
  text_style.color = SK_ColorBLACK;
  while (state.KeepRunning()) {
    builder.PushStyle(text_style);
    builder.Pop();
  }
}
BENCHMARK(BM_ParagraphBuilderPushPop);

static void BM_ParagraphBuilderAddTextString(benchmark::State& state) {
  std::u16string text = u"Hello World";

  auto font_collection = GetTestFontCollection();

  txt::ParagraphStyle paragraph_style;

  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.AddText(text);
  }
}
BENCHMARK(BM_ParagraphBuilderAddTextString);

static void BM_ParagraphBuilderAddTextChar(benchmark::State& state) {
  std::u16string text = u"Hello World";

  txt::ParagraphStyle paragraph_style;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.AddText(text);
  }
}
BENCHMARK(BM_ParagraphBuilderAddTextChar);

static void BM_ParagraphBuilderAddTextU16stringShort(benchmark::State& state) {
  const char* text = "H";
  auto icu_text = icu::UnicodeString::fromUTF8(text);
  std::u16string u16_text(icu_text.getBuffer(),
                          icu_text.getBuffer() + icu_text.length());

  txt::ParagraphStyle paragraph_style;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.AddText(u16_text);
  }
}
BENCHMARK(BM_ParagraphBuilderAddTextU16stringShort);

static void BM_ParagraphBuilderAddTextU16stringLong(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.";
  auto icu_text = icu::UnicodeString::fromUTF8(text);
  std::u16string u16_text(icu_text.getBuffer(),
                          icu_text.getBuffer() + icu_text.length());

  auto font_collection = GetTestFontCollection();

  txt::ParagraphStyle paragraph_style;

  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.AddText(u16_text);
  }
}
BENCHMARK(BM_ParagraphBuilderAddTextU16stringLong);

static void BM_ParagraphBuilderShortParagraphConstruct(
    benchmark::State& state) {
  const char* text = "Hello World";
  auto icu_text = icu::UnicodeString::fromUTF8(text);
  std::u16string u16_text(icu_text.getBuffer(),
                          icu_text.getBuffer() + icu_text.length());

  txt::ParagraphStyle paragraph_style;

  txt::TextStyle text_style;
  text_style.color = SK_ColorBLACK;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.PushStyle(text_style);
    builder.AddText(u16_text);
    builder.Pop();
    auto paragraph = builder.Build();
  }
}
BENCHMARK(BM_ParagraphBuilderShortParagraphConstruct);

static void BM_ParagraphBuilderLongParagraphConstruct(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.";
  auto icu_text = icu::UnicodeString::fromUTF8(text);
  std::u16string u16_text(icu_text.getBuffer(),
                          icu_text.getBuffer() + icu_text.length());

  txt::ParagraphStyle paragraph_style;

  txt::TextStyle text_style;
  text_style.color = SK_ColorBLACK;
  auto font_collection = GetTestFontCollection();
  while (state.KeepRunning()) {
    txt::ParagraphBuilderTxt builder(paragraph_style, font_collection);
    builder.PushStyle(text_style);
    builder.AddText(u16_text);
    builder.Pop();
    auto paragraph = builder.Build();
  }
}
BENCHMARK(BM_ParagraphBuilderLongParagraphConstruct);

}  // namespace txt