/*
 * 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 "hb-test.h"

/* Unit tests for hb-map.h */


static void
assert_map_has (const hb_map_t *m, hb_codepoint_t key, hb_codepoint_t value)
{
  g_assert_true (hb_map_has (m, key));
  g_assert_cmpint (hb_map_get (m, key), ==, value);
}

static void
test_map_basic (void)
{
  hb_map_t *empty = hb_map_get_empty ();
  hb_map_t *m;
  g_assert_true (hb_map_is_empty (empty));
  g_assert_true (!hb_map_allocation_successful (empty));
  hb_map_destroy (empty);

  m = hb_map_create ();
  g_assert_true (hb_map_allocation_successful (m));
  g_assert_true (hb_map_is_empty (m));

  hb_map_set (m, 213, 223);
  hb_map_set (m, 643, 675);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);

  g_assert_cmpint (hb_map_get (m, 213), ==, 223);
  g_assert_true (!hb_map_has (m, 123));
  g_assert_true (hb_map_has (m, 213));

  hb_map_del (m, 213);
  g_assert_true (!hb_map_has (m, 213));

  g_assert_cmpint (hb_map_get (m, 643), ==, 675);
  hb_map_set (m, 237, 673);
  g_assert_true (hb_map_has (m, 237));
  hb_map_clear (m);
  g_assert_true (!hb_map_has (m, 237));
  g_assert_true (!hb_map_has (m, 643));
  g_assert_cmpint (hb_map_get_population (m), ==, 0);

  hb_map_destroy (m);
}

static void
test_map_copy_equal_hash_update (void)
{
  hb_map_t *m = hb_map_create ();
  hb_map_t *copy;
  hb_map_t *updated;

  hb_map_set (m, 11, 101);
  hb_map_set (m, 22, 202);

  copy = hb_map_copy (m);
  g_assert_true (hb_map_allocation_successful (copy));
  g_assert_true (hb_map_is_equal (m, copy));
  g_assert_true (hb_map_is_equal (copy, m));
  g_assert_cmpint (hb_map_hash (m), ==, hb_map_hash (copy));

  hb_map_set (m, 33, 303);
  g_assert_true (!hb_map_is_equal (m, copy));
  g_assert_true (!hb_map_has (copy, 33));
  assert_map_has (copy, 11, 101);
  assert_map_has (copy, 22, 202);

  updated = hb_map_create ();
  hb_map_set (updated, 22, 222);
  hb_map_set (updated, 44, 404);
  hb_map_update (copy, updated);

  g_assert_cmpint (hb_map_get_population (copy), ==, 3);
  assert_map_has (copy, 11, 101);
  assert_map_has (copy, 22, 222);
  assert_map_has (copy, 44, 404);
  assert_map_has (m, 22, 202);

  hb_map_destroy (updated);
  hb_map_destroy (copy);
  hb_map_destroy (m);
}

static void
test_map_next_keys_values (void)
{
  hb_map_t *m = hb_map_create ();
  hb_set_t *iter_keys = hb_set_create ();
  hb_set_t *iter_values = hb_set_create ();
  hb_set_t *keys = hb_set_create ();
  hb_set_t *values = hb_set_create ();
  hb_codepoint_t key;
  hb_codepoint_t value;
  unsigned int count = 0;
  int idx = -1;

  hb_map_set (m, 7, 70);
  hb_map_set (m, 19, 190);
  hb_map_set (m, 23, 190);

  while (hb_map_next (m, &idx, &key, &value))
  {
    g_assert_true (!hb_set_has (iter_keys, key));
    assert_map_has (m, key, value);
    hb_set_add (iter_keys, key);
    hb_set_add (iter_values, value);
    count++;
  }

  g_assert_cmpint (count, ==, hb_map_get_population (m));
  g_assert_cmpint (hb_set_get_population (iter_keys), ==, 3);
  g_assert_true (hb_set_has (iter_keys, 7));
  g_assert_true (hb_set_has (iter_keys, 19));
  g_assert_true (hb_set_has (iter_keys, 23));
  g_assert_cmpint (hb_set_get_population (iter_values), ==, 2);
  g_assert_true (hb_set_has (iter_values, 70));
  g_assert_true (hb_set_has (iter_values, 190));

  hb_map_keys (m, keys);
  hb_map_values (m, values);

  g_assert_true (hb_set_is_equal (keys, iter_keys));
  g_assert_true (hb_set_is_equal (values, iter_values));

  hb_set_destroy (values);
  hb_set_destroy (keys);
  hb_set_destroy (iter_values);
  hb_set_destroy (iter_keys);
  hb_map_destroy (m);
}

static void
test_map_userdata (void)
{
  hb_map_t *m = hb_map_create ();

  hb_user_data_key_t key[2];
  int *data = (int *) malloc (sizeof (int));
  int *data2;
  *data = 3123;
  hb_map_set_user_data (m, &key[0], data, free, TRUE);
  g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 3123);

  data2 = (int *) malloc (sizeof (int));
  *data2 = 6343;
  hb_map_set_user_data (m, &key[0], data2, free, FALSE);
  g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 3123);
  hb_map_set_user_data (m, &key[0], data2, free, TRUE);
  g_assert_cmpint (*((int *) hb_map_get_user_data (m, &key[0])), ==, 6343);

  hb_map_destroy (m);
}

static void
test_map_refcount (void)
{
  hb_map_t *m = hb_map_create ();
  hb_map_t *m2;
  hb_map_set (m, 213, 223);
  g_assert_cmpint (hb_map_get (m, 213), ==, 223);

  m2 = hb_map_reference (m);
  hb_map_destroy (m);

  /* We copied its reference so it is still usable after one destroy */
  g_assert_true (hb_map_has (m, 213));
  g_assert_true (hb_map_has (m2, 213));

  hb_map_destroy (m2);

  /* Now you can't access them anymore */
}

static void
test_map_get_population (void)
{
  hb_map_t *m = hb_map_create ();

  hb_map_set (m, 12, 21);
  g_assert_cmpint (hb_map_get_population (m), ==, 1);
  hb_map_set (m, 78, 87);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);

  hb_map_set (m, 78, 87);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);
  hb_map_set (m, 78, 13);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);

  hb_map_set (m, 95, 56);
  g_assert_cmpint (hb_map_get_population (m), ==, 3);

  hb_map_del (m, 78);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);

  hb_map_del (m, 103);
  g_assert_cmpint (hb_map_get_population (m), ==, 2);

  hb_map_destroy (m);
}

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

  hb_test_add (test_map_basic);
  hb_test_add (test_map_copy_equal_hash_update);
  hb_test_add (test_map_next_keys_values);
  hb_test_add (test_map_userdata);
  hb_test_add (test_map_refcount);
  hb_test_add (test_map_get_population);

  return hb_test_run();
}
