/*
 * 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.h>
#include <hb-gpu.h>

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cinttypes>
#include <chrono>

int
main (int argc, char **argv)
{
  const char *font_path = nullptr;
  unsigned num_iters = 1;

  for (int i = 1; i < argc; i++)
  {
    if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
    {
      fprintf (stderr, "Usage: %s [-n iterations] FONTFILE\n", argv[0]);
      return 0;
    }
    if (!strcmp (argv[i], "-n") && i + 1 < argc)
    {
      num_iters = atoi (argv[++i]);
      if (!num_iters) num_iters = 1;
      continue;
    }
    font_path = argv[i];
  }

  if (!font_path)
  {
    fprintf (stderr, "Usage: %s [-n iterations] FONTFILE\n", argv[0]);
    return 1;
  }

  hb_blob_t *blob = hb_blob_create_from_file_or_fail (font_path);
  if (!blob)
  {
    fprintf (stderr, "Failed to open font file: %s\n", font_path);
    return 1;
  }

  hb_face_t *face = hb_face_create (blob, 0);
  hb_font_t *font = hb_font_create (face);
  unsigned glyph_count = hb_face_get_glyph_count (face);

  if (!glyph_count)
  {
    fprintf (stderr, "Font has no glyphs.\n");
    hb_font_destroy (font);
    hb_face_destroy (face);
    hb_blob_destroy (blob);
    return 1;
  }

  hb_gpu_paint_t *paint = hb_gpu_paint_create_or_fail ();
  hb_gpu_draw_t  *draw  = hb_gpu_draw_create_or_fail ();
  if (!paint || !draw)
  {
    fprintf (stderr, "Failed to create GPU encoder.\n");
    hb_gpu_paint_destroy (paint);
    hb_gpu_draw_destroy (draw);
    hb_font_destroy (font);
    hb_face_destroy (face);
    hb_blob_destroy (blob);
    return 1;
  }

  unsigned num_paint_encoded = 0;
  unsigned num_draw_encoded  = 0;
  unsigned num_empty = 0;
  unsigned num_failed = 0;
  uint64_t paint_bytes = 0;
  uint64_t draw_bytes  = 0;
  unsigned paint_max_bytes = 0;
  unsigned draw_max_bytes  = 0;
  unsigned paint_max_gid = 0;
  unsigned draw_max_gid  = 0;
  uint64_t paint_walk_ns   = 0;
  uint64_t paint_encode_ns = 0;
  uint64_t draw_walk_ns    = 0;
  uint64_t draw_encode_ns  = 0;

  typedef std::chrono::steady_clock clock;
  clock::time_point wall_start = clock::now ();

  for (unsigned iter = 0; iter < num_iters; iter++)
  for (unsigned gid = 0; gid < glyph_count; gid++)
  {
    hb_gpu_paint_clear (paint);

    clock::time_point t0 = clock::now ();
    hb_gpu_paint_glyph (paint, font, gid);
    clock::time_point t1 = clock::now ();

    hb_blob_t *encoded = hb_gpu_paint_encode (paint, nullptr);
    clock::time_point t2 = clock::now ();

    paint_walk_ns   += std::chrono::duration_cast<std::chrono::nanoseconds> (t1 - t0).count ();
    paint_encode_ns += std::chrono::duration_cast<std::chrono::nanoseconds> (t2 - t1).count ();

    bool is_fallback = false;
    if (!encoded)
    {
      /* Paint did not produce a blob (v1 feature, empty glyph).
       * Fall back to the draw encoder. */
      hb_gpu_draw_clear (draw);
      clock::time_point f0 = clock::now ();
      hb_gpu_draw_glyph (draw, font, gid);
      clock::time_point f1 = clock::now ();
      encoded = hb_gpu_draw_encode (draw, nullptr);
      clock::time_point f2 = clock::now ();
      draw_walk_ns   += std::chrono::duration_cast<std::chrono::nanoseconds> (f1 - f0).count ();
      draw_encode_ns += std::chrono::duration_cast<std::chrono::nanoseconds> (f2 - f1).count ();
      is_fallback = true;
    }

    if (!encoded)
    {
      if (iter == 0)
      {
	fprintf (stderr, "gid %u: encode failed\n", gid);
	num_failed++;
      }
      continue;
    }

    if (iter == 0)
    {
      unsigned len = hb_blob_get_length (encoded);
      if (len == 0)
	num_empty++;
      else if (is_fallback)
      {
	num_draw_encoded++;
	draw_bytes += len;
	if (len > draw_max_bytes) { draw_max_bytes = len; draw_max_gid = gid; }
      }
      else
      {
	num_paint_encoded++;
	paint_bytes += len;
	if (len > paint_max_bytes) { paint_max_bytes = len; paint_max_gid = gid; }
      }
    }
    if (is_fallback)
      hb_gpu_draw_recycle_blob (draw, encoded);
    else
      hb_gpu_paint_recycle_blob (paint, encoded);
  }

  uint64_t wall_ns = std::chrono::duration_cast<std::chrono::nanoseconds> (clock::now () - wall_start).count ();

  printf ("font:          %s\n", font_path);
  printf ("glyphs:        %u\n", glyph_count);
  printf ("empty:         %u\n", num_empty);
  if (num_failed)
    printf ("FAILED:        %u\n", num_failed);

  uint64_t total_glyphs = (uint64_t) glyph_count * num_iters;

  if (num_paint_encoded)
  {
    printf ("\n");
    printf ("paint encoded: %u\n", num_paint_encoded);
    printf ("  total:       %.2f KiB\n", paint_bytes / 1024.);
    printf ("  avg:         %.2f KiB/glyph\n",
	    paint_bytes / 1024. / num_paint_encoded);
    printf ("  max:         %.2f KiB (gid %u)\n",
	    paint_max_bytes / 1024., paint_max_gid);
    printf ("  walk:        %.3fms (%.1fus/glyph)\n",
	    paint_walk_ns / 1e6 / num_iters,
	    total_glyphs ? paint_walk_ns / 1e3 / total_glyphs : 0.);
    printf ("  encode:      %.3fms (%.1fus/glyph)\n",
	    paint_encode_ns / 1e6 / num_iters,
	    total_glyphs ? paint_encode_ns / 1e3 / total_glyphs : 0.);
  }

  if (num_draw_encoded)
  {
    printf ("\n");
    printf ("draw fallback: %u\n", num_draw_encoded);
    printf ("  total:       %.2f KiB\n", draw_bytes / 1024.);
    printf ("  avg:         %.2f KiB/glyph\n",
	    draw_bytes / 1024. / num_draw_encoded);
    printf ("  max:         %.2f KiB (gid %u)\n",
	    draw_max_bytes / 1024., draw_max_gid);
    printf ("  walk:        %.3fms (%.1fus/glyph)\n",
	    draw_walk_ns / 1e6 / num_iters,
	    num_draw_encoded ? draw_walk_ns / 1e3 / num_draw_encoded : 0.);
    printf ("  encode:      %.3fms (%.1fus/glyph)\n",
	    draw_encode_ns / 1e6 / num_iters,
	    num_draw_encoded ? draw_encode_ns / 1e3 / num_draw_encoded : 0.);
  }

  printf ("\n");
  printf ("wall:     %.3fms (%.0f glyphs/s)\n",
	  wall_ns / 1e6 / num_iters,
	  wall_ns ? total_glyphs * 1e9 / wall_ns : 0.);

  hb_gpu_paint_destroy (paint);
  hb_gpu_draw_destroy (draw);
  hb_font_destroy (font);
  hb_face_destroy (face);
  hb_blob_destroy (blob);

  return num_failed ? 1 : 0;
}
