/*
 * 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 (const char *backend)
{
  bool ret = hb_font_set_funcs_using (font, backend);
  g_assert (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++)
    test_body (*font_funcs);

  hb_buffer_destroy (ref_buffer);

  hb_font_destroy (font);
  hb_face_destroy (face);

  return 0;
}
