/*
 * Copyright (C) 2026  Behdad Esfahbod
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Author(s): Behdad Esfahbod
 */

#include "hb-benchmark.hh"

#include <hb-gpu.h>

#include <glib.h>

#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"

static struct test_input_t
{
  const char *font_path;
} default_tests[] =
{
  {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf"},
  {SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf"},
  {SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf"},
  {SUBSET_FONT_BASE_PATH "Comfortaa-Regular-new.ttf"},
  {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf"},
  {SUBSET_FONT_BASE_PATH "NotoSerifMyanmar-Regular.otf"},
};

static test_input_t *tests = default_tests;
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);

static void BM_GpuDrawEncode (benchmark::State &state,
			   const test_input_t &test_input)
{
  hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
  if (!face)
  {
    state.SkipWithError ("Failed to open font file");
    return;
  }

  hb_font_t *font = hb_font_create (face);
  unsigned num_glyphs = hb_face_get_glyph_count (face);
  hb_gpu_draw_t *draw = hb_gpu_draw_create_or_fail ();
  assert (draw);

  for (auto _ : state)
    for (unsigned gid = 0; gid < num_glyphs; ++gid)
    {
      hb_gpu_draw_clear (draw);
      hb_gpu_draw_glyph (draw, font, gid);
      hb_blob_t *blob = hb_gpu_draw_encode (draw, nullptr);
      hb_gpu_draw_recycle_blob (draw, blob);
    }

  hb_gpu_draw_destroy (draw);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static void BM_GpuPaintEncode (benchmark::State &state,
				const test_input_t &test_input)
{
  hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
  if (!face)
  {
    state.SkipWithError ("Failed to open font file");
    return;
  }

  hb_font_t *font = hb_font_create (face);
  unsigned num_glyphs = hb_face_get_glyph_count (face);
  hb_gpu_paint_t *paint = hb_gpu_paint_create_or_fail ();
  assert (paint);

  for (auto _ : state)
    for (unsigned gid = 0; gid < num_glyphs; ++gid)
    {
      hb_gpu_paint_glyph (paint, font, gid);
      hb_blob_t *blob = hb_gpu_paint_encode (paint, nullptr);
      if (blob)
	hb_gpu_paint_recycle_blob (paint, blob);
    }

  hb_gpu_paint_destroy (paint);
  hb_font_destroy (font);
  hb_face_destroy (face);
}

static const char *font_file = nullptr;

static GOptionEntry entries[] =
{
  {"font-file", 0, 0, G_OPTION_ARG_STRING, &font_file, "Font file-path to benchmark", "FONTFILE"},
  {nullptr}
};

int main (int argc, char **argv)
{
  benchmark::Initialize (&argc, argv);

  GOptionContext *context = g_option_context_new ("");
  g_option_context_set_summary (context, "Benchmark GPU glyph encoding");
  g_option_context_add_main_entries (context, entries, nullptr);
  g_option_context_parse (context, &argc, &argv, nullptr);
  g_option_context_free (context);

  argc--;
  argv++;
  if (!font_file && argc)
  {
    font_file = *argv;
    argc--;
    argv++;
  }

  if (font_file)
  {
    num_tests = 1;
    tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
    tests[0].font_path = font_file;
  }

  for (unsigned i = 0; i < num_tests; i++)
  {
    auto &test_input = tests[i];
    const char *base = strrchr (test_input.font_path, '/');
    base = base ? base + 1 : test_input.font_path;

    char draw_name[1024] = "BM_GpuDrawEncode/";
    strcat (draw_name, base);
    benchmark::RegisterBenchmark (draw_name, BM_GpuDrawEncode, test_input)
      ->Unit (benchmark::kMillisecond);

    char paint_name[1024] = "BM_GpuPaintEncode/";
    strcat (paint_name, base);
    benchmark::RegisterBenchmark (paint_name, BM_GpuPaintEncode, test_input)
      ->Unit (benchmark::kMillisecond);
  }

  benchmark::RunSpecifiedBenchmarks ();
  benchmark::Shutdown ();

  if (tests != default_tests)
    free (tests);
}
