#include "hb-benchmark.hh"

enum operation_t
{
  subset_glyphs,
  subset_unicodes,
  instance,
};

struct axis_location_t
{
  hb_tag_t axis_tag;
  float axis_value;
};

static const axis_location_t
_roboto_flex_instance_opts[] =
{
  {HB_TAG ('w', 'g', 'h', 't'), 600.f},
  {HB_TAG ('w', 'd', 't', 'h'), 75.f},
  {HB_TAG ('o', 'p', 's', 'z'), 90.f},
  {HB_TAG ('G', 'R', 'A', 'D'), -100.f},
  {HB_TAG ('s', 'l', 'n', 't'), -3.f},
  {HB_TAG ('X', 'T', 'R', 'A'), 500.f},
  {HB_TAG ('X', 'O', 'P', 'Q'), 150.f},
  {HB_TAG ('Y', 'O', 'P', 'Q'), 100.f},
  {HB_TAG ('Y', 'T', 'L', 'C'), 480.f},
  {HB_TAG ('Y', 'T', 'U', 'C'), 600.f},
  {HB_TAG ('Y', 'T', 'A', 'S'), 800.f},
  {HB_TAG ('Y', 'T', 'D', 'E'), -50.f},
  {HB_TAG ('Y', 'T', 'F', 'I'), 600.f},
};

static const axis_location_t
_mplus_instance_opts[] =
{
  {HB_TAG ('w', 'g', 'h', 't'), 800.f},
};

static const axis_location_t
_fraunces_partial_instance_opts[] =
{
  {HB_TAG ('S', 'O', 'F', 'T'), 75.0f},
  {HB_TAG ('W', 'O', 'N', 'K'), 0.75f},
};

template <typename Type, unsigned int n>
static inline unsigned int ARRAY_LEN (const Type (&)[n]) { return n; }

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

struct test_input_t
{
  const char *font_path;
  unsigned max_subset_size;
  const axis_location_t *instance_opts;
  unsigned num_instance_opts;
} default_tests[] =
{
  {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 1000, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4096, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1400, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf", 300, nullptr, 0},
  {SUBSET_FONT_BASE_PATH "MPLUS1-Variable.ttf", 6000, _mplus_instance_opts, ARRAY_LEN (_mplus_instance_opts)},
  {SUBSET_FONT_BASE_PATH "RobotoFlex-Variable.ttf", 900, _roboto_flex_instance_opts, ARRAY_LEN (_roboto_flex_instance_opts)},
  {SUBSET_FONT_BASE_PATH "Fraunces.ttf", 900, _fraunces_partial_instance_opts, ARRAY_LEN (_fraunces_partial_instance_opts)},
#if 0
  {"perf/fonts/NotoSansCJKsc-VF.ttf", 100000},
#endif
};

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


void AddCodepoints(const hb_set_t* codepoints_in_font,
                   unsigned subset_size,
                   hb_subset_input_t* input)
{
  auto *unicodes = hb_subset_input_unicode_set (input);
  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
  for (unsigned i = 0; i < subset_size; i++) {
    // TODO(garretrieger): pick randomly.
    if (!hb_set_next (codepoints_in_font, &cp)) return;
    hb_set_add (unicodes, cp);
  }
}

void AddGlyphs(unsigned num_glyphs_in_font,
               unsigned subset_size,
               hb_subset_input_t* input)
{
  auto *glyphs = hb_subset_input_glyph_set (input);
  for (unsigned i = 0; i < subset_size && i < num_glyphs_in_font; i++) {
    if (i + 1 == subset_size &&
        hb_subset_input_get_flags (input) & HB_SUBSET_FLAGS_RETAIN_GIDS)
    {
      hb_set_add (glyphs, num_glyphs_in_font - 1);
      continue;
    }
    hb_set_add (glyphs, i);
  }
}

// Preprocess face and populate the subset accelerator on it to speed up
// the subsetting operations.
static hb_face_t* preprocess_face(hb_face_t* face)
{
  hb_face_t* new_face = hb_subset_preprocess(face);
  hb_face_destroy(face);
  return new_face;
}

static hb_face_t *cached_face;

static void
free_cached_face (void)
{
  hb_face_destroy (cached_face);
  cached_face = nullptr;
}


/* benchmark for subsetting a font */
static void BM_subset (benchmark::State &state,
                       operation_t operation,
                       const test_input_t &test_input,
                       bool retain_gids)
{
  unsigned subset_size = state.range(0);

  hb_face_t *face = nullptr;

  static const char *cached_font_path;

  if (!cached_font_path || strcmp (cached_font_path, test_input.font_path))
  {
    face = hb_benchmark_face_create_from_file_or_fail (test_input.font_path, 0);
    assert (face);

    face = preprocess_face (face);

    if (cached_face)
      hb_face_destroy (cached_face);

    cached_face = hb_face_reference (face);
    cached_font_path = test_input.font_path;
  }
  else
    face = hb_face_reference (cached_face);

  hb_subset_input_t* input = hb_subset_input_create_or_fail ();
  assert (input);

  if (retain_gids)
    hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS);

  switch (operation)
  {
    case subset_unicodes:
    {
      hb_set_t* all_codepoints = hb_set_create ();
      hb_face_collect_unicodes (face, all_codepoints);
      AddCodepoints(all_codepoints, subset_size, input);
      hb_set_destroy (all_codepoints);
    }
    break;

    case subset_glyphs:
    {
      unsigned num_glyphs = hb_face_get_glyph_count (face);
      AddGlyphs(num_glyphs, subset_size, input);
    }
    break;

    case instance:
    {
      hb_set_t* all_codepoints = hb_set_create ();
      hb_face_collect_unicodes (face, all_codepoints);
      AddCodepoints(all_codepoints, subset_size, input);
      hb_set_destroy (all_codepoints);

      hb_subset_input_set_flags(input, hb_subset_input_get_flags(input) | HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS);

      for (unsigned i = 0; i < test_input.num_instance_opts; i++)
        hb_subset_input_pin_axis_location (input, face,
                                           test_input.instance_opts[i].axis_tag,
                                           test_input.instance_opts[i].axis_value);
    }
    break;
  }

  for (auto _ : state)
  {
    hb_face_t* subset = hb_subset_or_fail (face, input);
    assert (subset);
    hb_face_destroy (subset);
  }

  hb_subset_input_destroy (input);
  hb_face_destroy (face);
}

static void test_subset (operation_t op,
                         const char *op_name,
                         bool retain_gids,
                         benchmark::TimeUnit time_unit,
                         const test_input_t &test_input)
{
  if (op == instance && test_input.instance_opts == nullptr)
    return;

  char name[1024] = "BM_subset/";
  strcat (name, op_name);
  strcat (name, "/");
  const char *p = strrchr (test_input.font_path, '/');
  strcat (name, p ? p + 1 : test_input.font_path);
  if (retain_gids)
    strcat (name, "/retaingids");

  benchmark::RegisterBenchmark (name, BM_subset, op, test_input, retain_gids)
      ->Range(10, test_input.max_subset_size)
      ->Unit(time_unit);
}

static void test_operation (operation_t op,
                            const char *op_name,
                            const test_input_t *tests,
                            unsigned num_tests,
                            benchmark::TimeUnit time_unit)
{
  for (unsigned i = 0; i < num_tests; i++)
  {
    auto& test_input = tests[i];
    test_subset (op, op_name, true, time_unit, test_input);
    test_subset (op, op_name, false, time_unit, test_input);
  }
}

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

#ifndef HB_NO_ATEXIT
  atexit (free_cached_face);
#endif

  if (argc > 1)
  {
    num_tests = (argc - 1) / 2;
    tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
    for (unsigned i = 0; i < num_tests; i++)
    {
      tests[i].font_path = argv[1 + i * 2];
      tests[i].max_subset_size = atoi (argv[2 + i * 2]);
    }
  }

#define TEST_OPERATION(op, time_unit) test_operation (op, #op, tests, num_tests, time_unit)

  TEST_OPERATION (subset_glyphs, benchmark::kMicrosecond);
  TEST_OPERATION (subset_unicodes, benchmark::kMicrosecond);
  TEST_OPERATION (instance, benchmark::kMicrosecond);

#undef TEST_OPERATION

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

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