/*
 * To build on Debian-based systems:
 *
 * $ gcc icu-test.c -licui18n -licuuc -o icu-coll-versions
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "unicode/ustring.h"
#include "unicode/ucol.h"
#include <unicode/ucnv.h>

#define DISPLAY_LOCALE		"en_US"
#define ICU_DISPLAY_LEN		512

static char	   *austrdup(const UChar* unichars);
static void		listLocales(void);

static char *
austrdup(const UChar* unichars)
{
	int			length;
	char	   *newString;

	length = u_strlen (unichars);
	newString = (char*) malloc(sizeof(char) * 4 * (length + 1));
	if (!newString)
		return NULL;

	u_austrcpy(newString, unichars);

	return newString;
}

static void
listLocales(void)
{
	int32_t		available;
	UErrorCode	status = U_ZERO_ERROR;
	int			i;

	/* Print header */
	printf("Display Name                                      | locale      | Language  | Country   | Valid     | Actual\n");
	printf("------------------------------------------------------------------------------------------------------------\n");

	available = uloc_countAvailable();
	for (i = 0; i < available; i++)
	{
		const char  *locale;
		UCollator	*collator = NULL;
		char		 language[512];
		char		 country[512];
		UChar		 displayName[512];
		const char *valid_locale_name;
		const char *actual_locale_name;
		int32_t		displayLength;
		size_t		len;

		/* Get locale*/
		locale = uloc_getAvailable(i);
		/* Open collator from that locale */
		collator = ucol_open(locale, &status);
		valid_locale_name = ucol_getLocaleByType(collator, ULOC_VALID_LOCALE, &status);
		actual_locale_name = ucol_getLocaleByType(collator, ULOC_ACTUAL_LOCALE, &status);
		uloc_getLanguage(locale, language, sizeof(language), &status);
		uloc_getCountry(locale, country, sizeof(country), &status);

		if (U_FAILURE(status))
		{
			printf("error with locale %s for ucol_open: code %d\n", locale, (int) status);
			ucol_close(collator);
			status = U_ZERO_ERROR;
			continue;
		}
		displayLength = ucol_getDisplayName(locale, DISPLAY_LOCALE,
											displayName, ICU_DISPLAY_LEN,
											&status);
		if (displayLength > ICU_DISPLAY_LEN)
		{
			printf("error with locale %s for ucol_getDisplayName: could not fit %d\n", locale, (int) displayLength);
			ucol_close(collator);
			status = U_ZERO_ERROR;
			continue;
		}

		if (U_FAILURE(status))
		{
			printf("error with locale %s for ucol_getDisplayName: code %d\n", locale, (int) status);
			ucol_close(collator);
			status = U_ZERO_ERROR;
			continue;
		}

		/* Print locale's collator details */
		printf("%-50s| %-12s| %-10s| %-10s| %-10s| %-10s\n",
			   austrdup(displayName),
			   locale,
			   language,
			   country,
			   valid_locale_name,
			   actual_locale_name);

		ucol_close(collator);
	}
}

int main(int argc, char **argv)
{
	listLocales();

	return 0;
}
