#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "unicode/charsets.h"
#include "unicode/encoding.h"

#include "internal.h"

struct table_entry {
	const char *alias;
	const char *encname;
};

static const struct table_entry mapping_table[] = {
	{"/ISO-8859-1/ISO8859-1/8859_1/ISO-IR-100/", "ISO-8859-1" },
	{"/ISO-8859-2/ISO8859-2/8859_2/ISO-IR-101/", "ISO-8859-2" },
	{"/ISO-8859-3/ISO8859-3/8859_3/ISO-IR-109/", "ISO-8859-3" },
	{"/ISO-8859-4/ISO8859-4/8859_4/ISO-IR-110/", "ISO-8859-4" },
	{"/ISO-8859-5/ISO8859-5/8859_5/ISO-IR-144/", "ISO-8859-5" },
	{"/ISO-8859-7/ISO8859-7/8859_7/ISO-IR-126/", "ISO-8859-7" },
	{"/ISO-8859-8/ISO8859-8/8859_8/ISO-IR-198/", "ISO-8859-8" },
	{"/ISO-8859-9/ISO8859-9/8859_9/ISO-IR-148/", "ISO-8859-9" },
	{"/ISO-8859-10/ISO8859-10/8859_10/ISO-IR-157/", "ISO-8859-10" },
	{"/ISO-8859-11/ISO8859-11/8859_11/ISO-IR-166/", "ISO-8859-11" },
	{"/ISO-8859-13/ISO8859-13/8859_13/ISO-IR-179/", "ISO-8859-13" },
	{"/ISO-8859-14/ISO8859-14/8859_14/ISO-IR-199/", "ISO-8859-14" },
	{"/ISO-8859-15/ISO8859-15/8859_15/ISO-IR-203/", "ISO-8859-15" },
	{"/SHIFT_JIS/X-SJIS/SHIFT-JIS/", "SHIFT_JIS" },
	{"/EUC-JP/EUCJP/", "EUC-JP" },
	{"/ISO-2022-KR/", "ISO-2022-KR" },
	{"/EUC-KR/EUCKR/", "EUC-KR" },
	{"/ISO-2022-JP/JIS_Encoding/", "ISO-2022-JP" },
	{"/ISO-2022-JP-1/", "ISO-2022-JP-1" },
	{"/ISO-2022-JP-2/", "ISO-2022-JP-2" },
	{"/ISO-2022-CN/", "ISO-2022-CN" },
	{"/ISO-2022-CN-EXT/", "ISO-2022-CN-EXT" },
	{"/UTF-7/UNICODE-1-1-UTF-7/UNICODE-2-0-UTF-7/", "UTF-7" },
	{"/UTF-8/UNICODE-1-1-UTF-8/UNICODE-2-0-UTF-8/", "UTF-8" },
	{"/ISO-10646-UCS-4/UCS-4/UTF-32/", "ISO-10646-UCS-4" },
	{"/UTF-16/UCS-2/ISO-10646-UCS-2/UNICODE-1-1/UNICODE-2-0/", "UTF-16" },
	{"/ISO-2022/", "ISO-2022" },
	{"/GB2312/CN-GB/GB_2312-80/EUC-CN/EUCCN/GBK/", "GB2312" },
	{"/BIG5/BIG-FIVE/BIG-5/CN-BIG5/BIG_FIVE/", "BIG5" },
	{"/ISO-IR-182/", "ISO-IR-182" },
	{"/ISO-IR-197/", "ISO-IR-197" },
	{"/JOHAB/", "JOHAB" },
	{"/SCSU/", "SCSU" },
	{"/X-ACORN-LATIN1/", "X-ACORN-LATIN1" },
	{"/X-ACORN-FUZZY/", "X-ACORN-FUZZY" },
	{"/X-CURRENT/X-SYSTEM/", "X-CURRENT" },
};

#define TABLE_SIZE (sizeof(mapping_table) / sizeof(mapping_table[0]))

/**
 * Look up an encoding number, based on its name
 *
 * \param name The encoding name
 * \return The encoding number, or 0 if not found.
 */
int iconv_encoding_number_from_name(const char *name)
{
	int i;
	char buf[256];

	snprintf(buf, sizeof buf, "/%s/", name);

	/* convert to upper case */
	for (i = 0; i != strlen(buf); i++) {
		if (buf[i] >= 'a' && buf[i] <= 'z')
			buf[i] = buf[i] - 32;
	}

	for (i = 0; i != TABLE_SIZE; i++)
		if (strstr(mapping_table[i].alias, buf) != NULL)
			return encoding_number_from_name(mapping_table[i].encname);

	return 0;
}

/**
 * Look up an encoding name, based on its MIB number
 *
 * \param number  The encoding MIB number
 * \return Pointer to encoding name, or NULL if not found
 */
const char *iconv_encoding_name_from_number(int number)
{
	const char *ret = NULL;
	/* This is a PITA - UnicodeLib doesn't have a call to do this,
	 * so implement it ourselves. */
	switch (number) {
		case csISOLatin1:
			ret = mapping_table[0].alias;
			break;
		case csISOLatin2:
			ret = mapping_table[1].alias;
			break;
		case csISOLatin3:
			ret = mapping_table[2].alias;
			break;
		case csISOLatin4:
			ret = mapping_table[3].alias;
			break;
		case csISOLatinCyrillic:
			ret = mapping_table[4].alias;
			break;
		case csISOLatinGreek:
			ret = mapping_table[5].alias;
			break;
		case csISOLatinHebrew:
			ret = mapping_table[6].alias;
			break;
		case csISOLatin5:
			ret = mapping_table[7].alias;
			break;
		case csISOLatin6:
			ret = mapping_table[8].alias;
			break;
		case csISOLatinThai:
			ret = mapping_table[9].alias;
			break;
		case csISOLatin7:
			ret = mapping_table[10].alias;
			break;
		case csISOLatin8:
			ret = mapping_table[11].alias;
			break;
		case csISOLatin9:
			ret = mapping_table[12].alias;
			break;
		case csShiftJIS:
			ret = mapping_table[13].alias;
			break;
		case csEUCPkdFmtJapanese:
			ret = mapping_table[14].alias;
			break;
		case csISO2022KR:
			ret = mapping_table[15].alias;
			break;
		case csEUCKR:
			ret = mapping_table[16].alias;
			break;
		case csISO2022JP:
			ret = mapping_table[17].alias;
			break;
		case csISO2022JP1:
			ret = mapping_table[18].alias;
			break;
		case csISO2022JP2:
			ret = mapping_table[19].alias;
			break;
		case csISO2022CN:
			ret = mapping_table[20].alias;
			break;
		case csISO2022CN_EXT:
			ret = mapping_table[21].alias;
			break;
		case csUnicode11UTF7:
			ret = mapping_table[22].alias;
			break;
		case csUTF8:
			ret = mapping_table[23].alias;
			break;
		case csUCS4:
			ret = mapping_table[24].alias;
			break;
		case csUnicode11:
			ret = mapping_table[25].alias;
			break;
		case csVenturaMath:
			ret = mapping_table[26].alias;
			break;
		case csGB2312:
			ret = mapping_table[27].alias;
			break;
		case csBig5:
			ret = mapping_table[28].alias;
			break;
		case csWelsh:
			ret = mapping_table[29].alias;
			break;
		case csSami:
			ret = mapping_table[30].alias;
			break;
		case csJohab:
			ret = mapping_table[31].alias;
			break;
		case csSCSU:
			ret = mapping_table[32].alias;
			break;
		case csAcornLatin1:
			ret = mapping_table[33].alias;
			break;
		case csAcornFuzzy:
			ret = mapping_table[34].alias;
			break;
		case csCurrent:
			ret = mapping_table[35].alias;
			break;
		default:
			break;
	}

	return ret;
}
