#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "/usr/include/unicode/utypes.h"
#include "/usr/include/unicode/ucol.h"


static UCollator *pg_ucol_open(const char *loc_str);
static int strncoll_icu_utf8(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, UCollator  *collator);
static size_t strnxfrm_prefix_icu_utf8(char *dest, size_t destsize, const char *src, ssize_t srclen, UCollator  *collator);


UCollator *
pg_ucol_open(const char *loc_str)
{
    UCollator  *collator;
    UErrorCode  status;

    if (loc_str == NULL)
	{
		printf("\nopening default collator is not supported\n");
		exit(1);
	}

    status = U_ZERO_ERROR;
    collator = ucol_open(loc_str, &status);
    if (U_FAILURE(status))
	{
		printf("\ncould not open collator for locale = %s\n", loc_str);
		exit(1);
	}

    return collator;
}

size_t
strnxfrm_prefix_icu_utf8(char *dest, size_t destsize,
                         const char *src, ssize_t srclen,
						 UCollator  *collator)
{
    size_t      result;
    UCharIterator iter;
    uint32_t    state[2];
    UErrorCode  status;

    uiter_setUTF8(&iter, src, srclen);
    state[0] = state[1] = 0;    /* won't need that again */
    status = U_ZERO_ERROR;
    result = ucol_nextSortKeyPart(collator,
                                  &iter,
                                  state,
                                  (uint8_t *) dest,
                                  destsize,
                                  &status);
    if (U_FAILURE(status))
	{
		printf("\nucol_nextSortKeyPart call failed\n");
		exit(1);
	}

    return result;
}

int
strncoll_icu_utf8(const char *arg1, ssize_t len1,
				  const char *arg2, ssize_t len2,
				  UCollator  *collator)
{
    int         result;
    UErrorCode  status;

    status = U_ZERO_ERROR;
    result = ucol_strcollUTF8(collator,
                              arg1, len1,
                              arg2, len2,
                              &status);
    if (U_FAILURE(status))
	{
		printf("\nucol_strcollUTF8 call failed\n");
		exit(1);
	}

    return result;
}

int main()
{
	char *str1 = "1";
	char *str2 = "a";
	char *dest1 = (char *) malloc(8);
	char *dest2 = (char *) malloc(8);
	char *collation = "ja-u-kr-latn-digit"; // This shows incorrect order in
											// ucol_strcollUTF8() and correct
											// order in ucol_nextSortKeyPart().
	/*
	char *collation = "ja-u-kr-digit-latn"; // This shows correct order in
											// both ucol_strcollUTF8() &
											// ucol_nextSortKeyPart().
	*/
	UCollator  *collator = pg_ucol_open(collation);
	size_t dest1_size;
	size_t dest2_size;


	printf("\nTesting sort order for '%s' & '%s' using ICU library with collation = '%s'\n", str1, str2, collation);

	printf("\nWith Method ucol_strcollUTF8():");
	if (strncoll_icu_utf8(str1, -1, str2, -1, collator) < 0)
		printf("\nSORT ORDER ASC : '%s', '%s'\n", str1, str2);
	else
		printf("\nSORT ORDER ASC : '%s', '%s'\n", str2, str1);

	printf("\nWith Method ucol_nextSortKeyPart() (i.e transform and memcmp):");
	dest1_size = strnxfrm_prefix_icu_utf8(dest1, 8, str1, -1, collator);
	dest2_size = strnxfrm_prefix_icu_utf8(dest2, 8, str2, -1, collator);
	//printf("\nTransformed dest1_size = %u, Transformed dest2_size = %u", dest1_size, dest2_size);

	if (memcmp(dest1, dest2, dest1_size) < 0)
		printf("\nSORT ORDER ASC : '%s', '%s'\n", str1, str2);
	else
		printf("\nSORT ORDER ASC : '%s', '%s'\n", str2, str1);
	
	printf("\nTesting Ends\n\n");
	return 0;
}
