/*
 * Copyright © 2018  Ebrahim Byagowi
 *
 *  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.
 *
 */

#include <pthread.h>

#include <hb.h>

#include "hb-test.h"

static const char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
static const char *text = "abc";

static int num_threads = 30;
static int num_iters = 200;

static hb_font_t *font;
static hb_buffer_t *ref_buffer;

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

static void
fill_the_buffer (hb_buffer_t *buffer)
{
  hb_buffer_add_utf8 (buffer, text, -1, 0, -1);
  hb_buffer_guess_segment_properties (buffer);
  hb_shape (font, buffer, NULL, 0);
}

static void
validity_check (hb_buffer_t *buffer) {
  if (hb_buffer_diff (ref_buffer, buffer, (hb_codepoint_t) -1, 0))
  {
    fprintf (stderr, "One of the buffers was different from the reference.\n");
    char out[255];

    hb_buffer_serialize_glyphs (buffer, 0, hb_buffer_get_length (ref_buffer),
				out, sizeof (out), NULL,
				font, HB_BUFFER_SERIALIZE_FORMAT_TEXT,
				HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES);
    fprintf (stderr, "Actual:   %s\n", out);

    hb_buffer_serialize_glyphs (ref_buffer, 0, hb_buffer_get_length (ref_buffer),
				out, sizeof (out), NULL,
				font, HB_BUFFER_SERIALIZE_FORMAT_TEXT,
				HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES);
    fprintf (stderr, "Expected: %s\n", out);

    exit (1);
  }
}

static void *
thread_func (void *data)
{
  hb_buffer_t *buffer = (hb_buffer_t *) data;

  pthread_mutex_lock (&mutex);
  pthread_mutex_unlock (&mutex);

  int i;
  for (i = 0; i < num_iters; i++)
  {
    hb_buffer_clear_contents (buffer);
    fill_the_buffer (buffer);
    validity_check (buffer);
  }

  return 0;
}

static void
test_body (gconstpointer data)
{
  const char *backend = (const char *) data;
  bool ret = hb_font_set_funcs_using (font, backend);
  g_assert_true (ret);

  int i;
  pthread_t *threads = calloc (num_threads, sizeof (pthread_t));
  hb_buffer_t **buffers = calloc (num_threads, sizeof (hb_buffer_t *));

  pthread_mutex_lock (&mutex);

  for (i = 0; i < num_threads; i++)
  {
    hb_buffer_t *buffer = hb_buffer_create ();
    buffers[i] = buffer;
    pthread_create (&threads[i], NULL, thread_func, buffer);
  }

  /* Let them loose! */
  pthread_mutex_unlock (&mutex);

  for (i = 0; i < num_threads; i++)
  {
    pthread_join (threads[i], NULL);
    hb_buffer_destroy (buffers[i]);
  }

  free (buffers);
  free (threads);
}

int
main (int argc, char **argv)
{
  hb_test_init (&argc, &argv);

  char *path = argc > 1 && *argv[1] ? argv[1] : (char *) font_path;
  if (argc > 2)
    num_threads = atoi (argv[2]);
  if (argc > 3)
    num_iters = atoi (argv[3]);
  if (argc > 4)
    text = argv[4];

  /* Dummy call to alleviate _guess_segment_properties thread safety-ness
   * https://github.com/harfbuzz/harfbuzz/issues/1191 */
  hb_language_get_default ();

  hb_face_t *face = hb_test_open_font_file (path);
  font = hb_font_create (face);

  /* Fill the reference */
  ref_buffer = hb_buffer_create ();
  fill_the_buffer (ref_buffer);

  for (const char **font_funcs = hb_font_list_funcs (); *font_funcs; font_funcs++)
    hb_test_add_data_flavor (*font_funcs, *font_funcs, test_body);

  int ret = hb_test_run ();

  hb_buffer_destroy (ref_buffer);

  hb_font_destroy (font);
  hb_face_destroy (face);

  return ret;
}
