#include "il2cpp-config.h"
#include "icalls/mscorlib/System.Text/Encoding.h"

#include <ctype.h>
#include <string>

#include "os/Encoding.h"
#include "vm/String.h"
#include "utils/StringUtils.h"


namespace il2cpp
{
namespace icalls
{
namespace mscorlib
{
namespace System
{
namespace Text
{
    static const char *encodings[] =
    {
        (char*)1,
        "ascii", "us_ascii", "us", "ansi_x3.4_1968",
        "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
        "iso_ir_6", "iso646_us", "iso_646.irv:1991",
        (char*)2,
        "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
        "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
        "x_unicode_2_0_utf_7",
        (char*)3,
        "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
        "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
        (char*)4,
        "utf_16", "UTF_16LE", "ucs_2", "unicode",
        "iso_10646_ucs2",
        (char*)5,
        "unicodefffe", "utf_16be",
        (char*)6,
        "iso_8859_1",
        (char*)0
    };

    Il2CppString* Encoding::InternalCodePage(int32_t *resultCodePage)
    {
        const int32_t want_name = *resultCodePage;

        *resultCodePage = -1;

        const std::string charSet = os::Encoding::GetCharSet();

        std::string codepage(charSet);

        for (size_t i = 0, length = codepage.length(); i < length; ++i)
        {
            char& c = codepage[i];

            if (isalpha(c))
                c = tolower(c);

            if (c == '-')
                c = '_';
        }

        // handle some common aliases
        const char* p = encodings[0];
        int code = 0;

        for (size_t i = 0; p != 0;)
        {
            if ((size_t)p < 7)
            {
                code = (int)(size_t)p;
                p = encodings[++i];
                continue;
            }

            if (codepage == p)
            {
                *resultCodePage = code;
                break;
            }

            p = encodings[++i];
        }

        if (codepage.find("utf_8") != std::string::npos)
            *resultCodePage |= 0x10000000;

        if (want_name && *resultCodePage == -1)
            return il2cpp::vm::String::NewWrapper(charSet.c_str());
        else
            return NULL;
    }
} /* namespace Text */
} /* namespace System */
} /* namespace mscorlib */
} /* namespace icalls */
} /* namespace il2cpp */
