/*
 * Copyright (C) 2011 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include <glib.h>

static int
int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
{
  const gint *i1 = p1;
  const gint *i2 = p2;

  return *i1 - *i2;
}

static void
test_sort_basic (void)
{
  gint *data;
  gint i;

  data = g_malloc (10000 * sizeof (int));
  for (i = 0; i < 10000; i++)
    {
      data[i] = g_random_int_range (0, 10000);
    }

  g_qsort_with_data (data, 10000, sizeof (int), int_compare_data, NULL);

  for (i = 1; i < 10000; i++)
    g_assert_cmpint (data[i -1], <=, data[i]);

  g_free (data);
}

typedef struct {
  int val;
  int i;
} SortItem;

typedef struct {
  int val;
  int i;
  int data[16];
} BigItem;

static int
item_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
{
  const SortItem *i1 = p1;
  const SortItem *i2 = p2;

  return i1->val - i2->val;
}

static void
test_sort_stable (void)
{
  SortItem *data;
  gint i;

  data = g_malloc (10000 * sizeof (SortItem));
  for (i = 0; i < 10000; i++)
    {
      data[i].val = g_random_int_range (0, 10000);
      data[i].i = i;
    }

  g_qsort_with_data (data, 10000, sizeof (SortItem), item_compare_data, NULL);

  for (i = 1; i < 10000; i++)
    {
      g_assert_cmpint (data[i -1].val, <=, data[i].val);
      if (data[i -1].val == data[i].val)
        g_assert_cmpint (data[i -1].i, <, data[i].i);
    }
  g_free (data);
}

static void
test_sort_big (void)
{
  BigItem *data;
  gint i;

  data = g_malloc (10000 * sizeof (BigItem));
  for (i = 0; i < 10000; i++)
    {
      data[i].val = g_random_int_range (0, 10000);
      data[i].i = i;
    }

  g_qsort_with_data (data, 10000, sizeof (BigItem), item_compare_data, NULL);

  for (i = 1; i < 10000; i++)
    {
      g_assert_cmpint (data[i -1].val, <=, data[i].val);
      if (data[i -1].val == data[i].val)
        g_assert_cmpint (data[i -1].i, <, data[i].i);
    }
  g_free (data);
}

int
main (int argc, char *argv[])
{
  g_test_init (&argc, &argv, NULL);

  g_test_add_func ("/sort/basic", test_sort_basic);
  g_test_add_func ("/sort/stable", test_sort_stable);
  g_test_add_func ("/sort/big", test_sort_big);

  return g_test_run ();
}

