/*
 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2.0,
 * as published by the Free Software Foundation.
 *
 * This program is designed to work with certain software (including
 * but not limited to OpenSSL) that is licensed under separate terms, as
 * designated in a particular file or component or in included license
 * documentation.  The authors of MySQL hereby grant you an additional
 * permission to link the program and your derivative works with the
 * separately licensed software that they have either included with
 * the program or referenced in the documentation.
 * This program 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 General Public License, version 2.0, for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 
 */

#include <algorithm>
#include <string>
#include <map>

#include "base/string_utilities.h"
#include "charset_utils.h"

static std::map<std::string, std::string> charsetToCollation{
  // Same content as returned from SHOW CHARACTER SET.
  { "big5", "big5_chinese_ci" },
  { "dec8", "dec8_swedish_ci" },
  { "cp850", "cp850_general_ci" },
  { "hp8", "hp8_english_ci" },
  { "koi8r", "koi8r_general_ci" },
  { "latin1", "latin1_swedish_ci" },
  { "latin2", "latin2_general_ci" },
  { "swe7", "swe7_swedish_ci" },
  { "ascii", "ascii_general_ci" },
  { "ujis", "ujis_japanese_ci" },
  { "sjis", "sjis_japanese_ci" },
  { "hebrew", "hebrew_general_ci" },
  { "tis620", "tis620_thai_ci" },
  { "euckr", "euckr_korean_ci" },
  { "koi8u", "koi8u_general_ci" },
  { "gb2312", "gb2312_chinese_ci" },
  { "greek", "greek_general_ci" },
  { "cp1250", "cp1250_general_ci" },
  { "gbk", "gbk_chinese_ci" },
  { "latin5", "latin5_turkish_ci" },
  { "armscii8", "armscii8_general_ci" },
  { "utf8", "utf8_general_ci" },
  { "ucs2", "ucs2_general_ci" },
  { "cp866", "cp866_general_ci" },
  { "keybcs2", "keybcs2_general_ci" },
  { "macce", "macce_general_ci" },
  { "macroman", "macroman_general_ci" },
  { "cp852", "cp852_general_ci" },
  { "latin7", "latin7_general_ci" },
  { "utf8mb4", "utf8mb4_general_ci" },
  { "cp1251", "cp1251_general_ci" },
  { "utf16", "utf16_general_ci" },
  { "utf16le", "utf16le_general_ci" },
  { "cp1256", "cp1256_general_ci" },
  { "cp1257", "cp1257_general_ci" },
  { "utf32", "utf32_general_ci" },
  { "binary", "binary" },
  { "geostd8", "geostd8_general_ci" },
  { "cp932", "cp932_japanese_ci" },
  { "eucjpms", "eucjpms_japanese_ci" },
  { "gb18030", "gb18030_chinese_ci" },
};

static std::map<std::string, std::string> collationToCharset{
  // Same order as returned from SHOW COLLATION.
  {"big5_chinese_ci", "big5"},
  {"big5_bin", "big5"},
  {"dec8_swedish_ci", "dec8"},
  {"dec8_bin", "dec8"},
  {"cp850_general_ci", "cp850"},
  {"cp850_bin", "cp850"},
  {"hp8_english_ci", "hp8"},
  {"hp8_bin", "hp8"},
  {"koi8r_general_ci", "koi8r"},
  {"koi8r_bin", "koi8r"},
  {"latin1_german1_ci", "latin1"},
  {"latin1_swedish_ci", "latin1"},
  {"latin1_danish_ci", "latin1"},
  {"latin1_german2_ci", "latin1"},
  {"latin1_bin", "latin1"},
  {"latin1_general_ci", "latin1"},
  {"latin1_general_cs", "latin1"},
  {"latin1_spanish_ci", "latin1"},
  {"latin2_czech_cs", "latin2"},
  {"latin2_general_ci", "latin2"},
  {"latin2_hungarian_ci", "latin2"},
  {"latin2_croatian_ci", "latin2"},
  {"latin2_bin", "latin2"},
  {"swe7_swedish_ci", "swe7"},
  {"swe7_bin", "swe7"},
  {"ascii_general_ci", "ascii"},
  {"ascii_bin", "ascii"},
  {"ujis_japanese_ci", "ujis"},
  {"ujis_bin", "ujis"},
  {"sjis_japanese_ci", "sjis"},
  {"sjis_bin", "sjis"},
  {"hebrew_general_ci", "hebrew"},
  {"hebrew_bin", "hebrew"},
  {"tis620_thai_ci", "tis620"},
  {"tis620_bin", "tis620"},
  {"euckr_korean_ci", "euckr"},
  {"euckr_bin", "euckr"},
  {"koi8u_general_ci", "koi8u"},
  {"koi8u_bin", "koi8u"},
  {"gb18030_chinese_ci", "gb18030"},
  {"gb18030_bin", "gb18030"},
  {"gb2312_chinese_ci", "gb2312"},
  {"gb2312_bin", "gb2312"},
  {"greek_general_ci", "greek"},
  {"greek_bin", "greek"},
  {"cp1250_general_ci", "cp1250"},
  {"cp1250_czech_cs", "cp1250"},
  {"cp1250_croatian_ci", "cp1250"},
  {"cp1250_bin", "cp1250"},
  {"cp1250_polish_ci", "cp1250"},
  {"gbk_chinese_ci", "gbk"},
  {"gbk_bin", "gbk"},
  {"latin5_turkish_ci", "latin5"},
  {"latin5_bin", "latin5"},
  {"armscii8_general_ci", "armscii8"},
  {"armscii8_bin", "armscii8"},
  {"utf8_general_ci", "utf8"},
  {"utf8_bin", "utf8"},
  {"utf8_unicode_ci", "utf8"},
  {"utf8_icelandic_ci", "utf8"},
  {"utf8_latvian_ci", "utf8"},
  {"utf8_romanian_ci", "utf8"},
  {"utf8_slovenian_ci", "utf8"},
  {"utf8_polish_ci", "utf8"},
  {"utf8_estonian_ci", "utf8"},
  {"utf8_spanish_ci", "utf8"},
  {"utf8_swedish_ci", "utf8"},
  {"utf8_turkish_ci", "utf8"},
  {"utf8_czech_ci", "utf8"},
  {"utf8_danish_ci", "utf8"},
  {"utf8_lithuanian_ci", "utf8"},
  {"utf8_slovak_ci", "utf8"},
  {"utf8_spanish2_ci", "utf8"},
  {"utf8_roman_ci", "utf8"},
  {"utf8_persian_ci", "utf8"},
  {"utf8_esperanto_ci", "utf8"},
  {"utf8_hungarian_ci", "utf8"},
  {"utf8_sinhala_ci", "utf8"},
  {"utf8_german2_ci", "utf8"},
  {"utf8_croatian_ci", "utf8"},
  {"utf8_unicode_520_ci", "utf8"},
  {"utf8_vietnamese_ci", "utf8"},
  {"utf8_general_mysql500_ci", "utf8"},
  {"ucs2_general_ci", "ucs2"},
  {"ucs2_bin", "ucs2"},
  {"ucs2_unicode_ci", "ucs2"},
  {"ucs2_icelandic_ci", "ucs2"},
  {"ucs2_latvian_ci", "ucs2"},
  {"ucs2_romanian_ci", "ucs2"},
  {"ucs2_slovenian_ci", "ucs2"},
  {"ucs2_polish_ci", "ucs2"},
  {"ucs2_estonian_ci", "ucs2"},
  {"ucs2_spanish_ci", "ucs2"},
  {"ucs2_swedish_ci", "ucs2"},
  {"ucs2_turkish_ci", "ucs2"},
  {"ucs2_czech_ci", "ucs2"},
  {"ucs2_danish_ci", "ucs2"},
  {"ucs2_lithuanian_ci", "ucs2"},
  {"ucs2_slovak_ci", "ucs2"},
  {"ucs2_spanish2_ci", "ucs2"},
  {"ucs2_roman_ci", "ucs2"},
  {"ucs2_persian_ci", "ucs2"},
  {"ucs2_esperanto_ci", "ucs2"},
  {"ucs2_hungarian_ci", "ucs2"},
  {"ucs2_sinhala_ci", "ucs2"},
  {"ucs2_german2_ci", "ucs2"},
  {"ucs2_croatian_ci", "ucs2"},
  {"ucs2_unicode_520_ci", "ucs2"},
  {"ucs2_vietnamese_ci", "ucs2"},
  {"ucs2_general_mysql500_ci", "ucs2"},
  {"cp866_general_ci", "cp866"},
  {"cp866_bin", "cp866"},
  {"keybcs2_general_ci", "keybcs2"},
  {"keybcs2_bin", "keybcs2"},
  {"macce_general_ci", "macce"},
  {"macce_bin", "macce"},
  {"macroman_general_ci", "macroman"},
  {"macroman_bin", "macroman"},
  {"cp852_general_ci", "cp852"},
  {"cp852_bin", "cp852"},
  {"latin7_estonian_cs", "latin7"},
  {"latin7_general_ci", "latin7"},
  {"latin7_general_cs", "latin7"},
  {"latin7_bin", "latin7"},
  {"utf8mb4_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_0900_as_ci", "utf8mb4"},
  {"utf8mb4_0900_as_cs", "utf8mb4"},
  {"utf8mb4_bin", "utf8mb4"},
  {"utf8mb4_croatian_ci", "utf8mb4"},
  {"utf8mb4_cs_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_cs_0900_as_cs", "utf8mb4"},
  {"utf8mb4_czech_ci", "utf8mb4"},
  {"utf8mb4_danish_ci", "utf8mb4"},
  {"utf8mb4_da_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_da_0900_as_cs", "utf8mb4"},
  {"utf8mb4_de_pb_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_de_pb_0900_as_cs", "utf8mb4"},
  {"utf8mb4_eo_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_eo_0900_as_cs", "utf8mb4"},
  {"utf8mb4_esperanto_ci", "utf8mb4"},
  {"utf8mb4_estonian_ci", "utf8mb4"},
  {"utf8mb4_es_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_es_0900_as_cs", "utf8mb4"},
  {"utf8mb4_es_trad_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_es_trad_0900_as_cs", "utf8mb4"},
  {"utf8mb4_et_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_et_0900_as_cs", "utf8mb4"},
  {"utf8mb4_general_ci", "utf8mb4"},
  {"utf8mb4_german2_ci", "utf8mb4"},
  {"utf8mb4_hr_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_hr_0900_as_cs", "utf8mb4"},
  {"utf8mb4_hungarian_ci", "utf8mb4"},
  {"utf8mb4_hu_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_hu_0900_as_cs", "utf8mb4"},
  {"utf8mb4_icelandic_ci", "utf8mb4"},
  {"utf8mb4_is_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_is_0900_as_cs", "utf8mb4"},
  {"utf8mb4_ja_0900_as_cs", "utf8mb4"},
  {"utf8mb4_ja_0900_as_cs_ks", "utf8mb4"},
  {"utf8mb4_latvian_ci", "utf8mb4"},
  {"utf8mb4_la_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_la_0900_as_cs", "utf8mb4"},
  {"utf8mb4_lithuanian_ci", "utf8mb4"},
  {"utf8mb4_lt_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_lt_0900_as_cs", "utf8mb4"},
  {"utf8mb4_lv_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_lv_0900_as_cs", "utf8mb4"},
  {"utf8mb4_persian_ci", "utf8mb4"},
  {"utf8mb4_pl_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_pl_0900_as_cs", "utf8mb4"},
  {"utf8mb4_polish_ci", "utf8mb4"},
  {"utf8mb4_romanian_ci", "utf8mb4"},
  {"utf8mb4_roman_ci", "utf8mb4"},
  {"utf8mb4_ro_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_ro_0900_as_cs", "utf8mb4"},
  {"utf8mb4_ru_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_ru_0900_as_cs", "utf8mb4"},
  {"utf8mb4_sinhala_ci", "utf8mb4"},
  {"utf8mb4_sk_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_sk_0900_as_cs", "utf8mb4"},
  {"utf8mb4_slovak_ci", "utf8mb4"},
  {"utf8mb4_slovenian_ci", "utf8mb4"},
  {"utf8mb4_sl_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_sl_0900_as_cs", "utf8mb4"},
  {"utf8mb4_spanish2_ci", "utf8mb4"},
  {"utf8mb4_spanish_ci", "utf8mb4"},
  {"utf8mb4_sv_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_sv_0900_as_cs", "utf8mb4"},
  {"utf8mb4_swedish_ci", "utf8mb4"},
  {"utf8mb4_tr_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_tr_0900_as_cs", "utf8mb4"},
  {"utf8mb4_turkish_ci", "utf8mb4"},
  {"utf8mb4_unicode_520_ci", "utf8mb4"},
  {"utf8mb4_unicode_ci", "utf8mb4"},
  {"utf8mb4_vietnamese_ci", "utf8mb4"},
  {"utf8mb4_vi_0900_ai_ci", "utf8mb4"},
  {"utf8mb4_vi_0900_as_cs", "utf8mb4"},
  {"cp1251_bulgarian_ci", "cp1251"},
  {"cp1251_ukrainian_ci", "cp1251"},
  {"cp1251_bin", "cp1251"},
  {"cp1251_general_ci", "cp1251"},
  {"cp1251_general_cs", "cp1251"},
  {"utf16_general_ci", "utf16"},
  {"utf16_bin", "utf16"},
  {"utf16_unicode_ci", "utf16"},
  {"utf16_icelandic_ci", "utf16"},
  {"utf16_latvian_ci", "utf16"},
  {"utf16_romanian_ci", "utf16"},
  {"utf16_slovenian_ci", "utf16"},
  {"utf16_polish_ci", "utf16"},
  {"utf16_estonian_ci", "utf16"},
  {"utf16_spanish_ci", "utf16"},
  {"utf16_swedish_ci", "utf16"},
  {"utf16_turkish_ci", "utf16"},
  {"utf16_czech_ci", "utf16"},
  {"utf16_danish_ci", "utf16"},
  {"utf16_lithuanian_ci", "utf16"},
  {"utf16_slovak_ci", "utf16"},
  {"utf16_spanish2_ci", "utf16"},
  {"utf16_roman_ci", "utf16"},
  {"utf16_persian_ci", "utf16"},
  {"utf16_esperanto_ci", "utf16"},
  {"utf16_hungarian_ci", "utf16"},
  {"utf16_sinhala_ci", "utf16"},
  {"utf16_german2_ci", "utf16"},
  {"utf16_croatian_ci", "utf16"},
  {"utf16_unicode_520_ci", "utf16"},
  {"utf16_vietnamese_ci", "utf16"},
  {"utf16le_general_ci", "utf16le"},
  {"utf16le_bin", "utf16le"},
  {"cp1256_general_ci", "cp1256"},
  {"cp1256_bin", "cp1256"},
  {"cp1257_lithuanian_ci", "cp1257"},
  {"cp1257_bin", "cp1257"},
  {"cp1257_general_ci", "cp1257"},
  {"utf32_general_ci", "utf32"},
  {"utf32_bin", "utf32"},
  {"utf32_unicode_ci", "utf32"},
  {"utf32_icelandic_ci", "utf32"},
  {"utf32_latvian_ci", "utf32"},
  {"utf32_romanian_ci", "utf32"},
  {"utf32_slovenian_ci", "utf32"},
  {"utf32_polish_ci", "utf32"},
  {"utf32_estonian_ci", "utf32"},
  {"utf32_spanish_ci", "utf32"},
  {"utf32_swedish_ci", "utf32"},
  {"utf32_turkish_ci", "utf32"},
  {"utf32_czech_ci", "utf32"},
  {"utf32_danish_ci", "utf32"},
  {"utf32_lithuanian_ci", "utf32"},
  {"utf32_slovak_ci", "utf32"},
  {"utf32_spanish2_ci", "utf32"},
  {"utf32_roman_ci", "utf32"},
  {"utf32_persian_ci", "utf32"},
  {"utf32_esperanto_ci", "utf32"},
  {"utf32_hungarian_ci", "utf32"},
  {"utf32_sinhala_ci", "utf32"},
  {"utf32_german2_ci", "utf32"},
  {"utf32_croatian_ci", "utf32"},
  {"utf32_unicode_520_ci", "utf32"},
  {"utf32_vietnamese_ci", "utf32"},
  {"binary", "binary"},
  {"geostd8_general_ci", "geostd8"},
  {"geostd8_bin", "geostd8"},
  {"cp932_japanese_ci", "cp932"},
  {"cp932_bin", "cp932"},
  {"eucjpms_japanese_ci", "eucjpms"},
  {"eucjpms_bin", "eucjpms"},
  {"gb18030_chinese_ci", "gb18030"},
  {"gb18030_bin", "gb18030"},
  {"gb18030_unicode_520_ci", "gb18030"},
};

//--------------------------------------------------------------------------------------------------

std::string defaultCollationForCharset(const std::string &charsetName) {
  auto i = charsetToCollation.find(base::tolower(charsetName));
  if (i != charsetToCollation.end())
    return i->second;

  return "";
}

//--------------------------------------------------------------------------------------------------

/**
 * Returns the character set for a given collation.
 */
std::string charsetForCollation(const std::string &collationName) {
  auto i = collationToCharset.find(base::tolower(collationName));
  if (i != collationToCharset.end())
    return i->second;

  return "";
}

//--------------------------------------------------------------------------------------------------
