/*
 * Copyright 2023 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkAlphaType.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/encode/SkJpegEncoder.h"
#include "include/ports/SkFontMgr_empty.h"
#include "modules/skparagraph/include/DartTypes.h"
#include "modules/skparagraph/include/FontCollection.h"
#include "modules/skparagraph/include/Paragraph.h"
#include "modules/skparagraph/include/ParagraphBuilder.h"
#include "modules/skparagraph/include/ParagraphStyle.h"
#include "modules/skunicode/include/SkUnicode_icu.h"

#include <cstdio>
#include <cstdlib>
#include <memory>

// https://www.gutenberg.org/ebooks/72339
constexpr const char* story =
    "The landing port at Titan had not changed much in five years.\n"
    "The ship settled down on the scarred blast shield, beside the same trio "
    "of squat square buildings, and quickly disgorged its scanty quota of "
    "cargo and a lone passenger into the flexible tube that linked the loading "
    "hatch with the main building.\n"
    "As soon as the tube was disconnected, the ship screamed off through the "
    "murky atmosphere, seemingly glad to get away from Titan and head back to "
    "the more comfortable and settled parts of the Solar System.";

class OneFontStyleSet : public SkFontStyleSet {
 public:
  explicit OneFontStyleSet(sk_sp<SkTypeface> face) : face_(face) {}

 protected:
  int count() override { return 1; }
  void getStyle(int, SkFontStyle* out_style, SkString*) override {
    *out_style = SkFontStyle();
  }
  sk_sp<SkTypeface> createTypeface(int index) override { return face_; }
  sk_sp<SkTypeface> matchStyle(const SkFontStyle&) override { return face_; }

 private:
  sk_sp<SkTypeface> face_;
};

class OneFontMgr : public SkFontMgr {
 public:
  explicit OneFontMgr(sk_sp<SkTypeface> face)
      : face_(face), style_set_(sk_make_sp<OneFontStyleSet>(face)) {}

 protected:
  int onCountFamilies() const override { return 1; }
  void onGetFamilyName(int index, SkString* familyName) const override {
    *familyName = SkString("the-only-font-I-have");
  }
  sk_sp<SkFontStyleSet> onCreateStyleSet(int index) const override {
    return style_set_;
  }
  sk_sp<SkFontStyleSet> onMatchFamily(const char[]) const override {
    return style_set_;
  }

  sk_sp<SkTypeface> onMatchFamilyStyle(const char[],
                                       const SkFontStyle&) const override {
    return face_;
  }
  sk_sp<SkTypeface> onMatchFamilyStyleCharacter(
      const char familyName[], const SkFontStyle& style, const char* bcp47[],
      int bcp47Count, SkUnichar character) const override {
    return face_;
  }
  sk_sp<SkTypeface> onLegacyMakeTypeface(const char[],
                                         SkFontStyle) const override {
    return face_;
  }

  sk_sp<SkTypeface> onMakeFromData(sk_sp<SkData>, int) const override {
    std::abort();
    return nullptr;
  }
  sk_sp<SkTypeface> onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
                                          int) const override {
    std::abort();
    return nullptr;
  }
  sk_sp<SkTypeface> onMakeFromStreamArgs(
      std::unique_ptr<SkStreamAsset>, const SkFontArguments&) const override {
    std::abort();
    return nullptr;
  }
  sk_sp<SkTypeface> onMakeFromFile(const char[], int) const override {
    std::abort();
    return nullptr;
  }

 private:
  sk_sp<SkTypeface> face_;
  sk_sp<SkFontStyleSet> style_set_;
};

int main(int argc, char** argv) {
  if (argc != 3) {
    printf("Usage: %s <font.ttf> <name.jpg>", argv[0]);
    return 1;
  }

  SkFILEStream input(argv[1]);
  if (!input.isValid()) {
    printf("Cannot open input file %s\n", argv[1]);
    return 1;
  }
  sk_sp<SkData> font_data = SkData::MakeFromStream(&input, input.getLength());
  sk_sp<SkFontMgr> mgr = SkFontMgr_New_Custom_Empty();
  sk_sp<SkTypeface> face = mgr->makeFromData(font_data);
  if (!face) {
    printf("input font %s was not parsable by Freetype\n", argv[1]);
    return 1;
  }

  SkFILEWStream output(argv[2]);
  if (!output.isValid()) {
    printf("Cannot open output file %s\n", argv[2]);
    return 1;
  }

  auto fontCollection = sk_make_sp<skia::textlayout::FontCollection>();
  sk_sp<SkFontMgr> one_mgr = sk_make_sp<OneFontMgr>(face);
  fontCollection->setDefaultFontManager(one_mgr);

  constexpr int width = 200;
  sk_sp<SkSurface> surface =
      SkSurfaces::Raster(SkImageInfo::MakeN32(width, 200, kOpaque_SkAlphaType));
  SkCanvas* canvas = surface->getCanvas();
  canvas->clear(SK_ColorWHITE);

  SkPaint paint;
  paint.setAntiAlias(true);
  paint.setColor(SK_ColorBLACK);

  skia::textlayout::TextStyle style;
  style.setForegroundColor(paint);
  style.setFontFamilies({SkString("sans-serif")});
  style.setFontSize(10.5);
  skia::textlayout::ParagraphStyle paraStyle;
  paraStyle.setTextStyle(style);
  paraStyle.setTextAlign(skia::textlayout::TextAlign::kRight);

  sk_sp<SkUnicode> unicode = SkUnicodes::ICU::Make();
  if (!unicode) {
    printf("Could not load unicode data\n");
    return 1;
  }
  using skia::textlayout::ParagraphBuilder;
  std::unique_ptr<ParagraphBuilder> builder =
      ParagraphBuilder::make(paraStyle, fontCollection, unicode);
  builder->addText(story);

  std::unique_ptr<skia::textlayout::Paragraph> paragraph = builder->Build();
  paragraph->layout(width - 20);
  paragraph->paint(canvas, 10, 10);

  SkPixmap pixmap;
  if (surface->peekPixels(&pixmap)) {
    if (!SkJpegEncoder::Encode(&output, pixmap, {})) {
      printf("Cannot write output\n");
      return 1;
    }
  } else {
    printf("Cannot readback on surface\n");
    return 1;
  }

  return 0;
}
