/*
 * 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 <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.png>", 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);

  using skia::textlayout::ParagraphBuilder;
  std::unique_ptr<ParagraphBuilder> builder =
      ParagraphBuilder::make(paraStyle, fontCollection);
  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;
}
