#include "Json_Utilities.hpp"

extern "C"
{
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
}

#include "functional"

/**
 * @brief Json文件 格式检查
 * @param path_to_file 文件路径串
 * @return std::string 错误值
 */
std::string JsonFile_FormatCheck(const char *path_to_file)
{
    // 尝试打开文件
    FILE *pFile = fopen(path_to_file, "rb");
    if (pFile == nullptr)
        return "file \"" + std::string(path_to_file) + "\" open failed.";

    // 行列计数
    size_t rol_count = 1;
    size_t column_count = 0;
    std::string err_str;

    // 跳过空白部分 return -> skip count
    auto Lambda_skip_blank = [&](void) -> size_t
    {
        size_t read_count = 0;
        while (true)
        {
            switch (fgetc(pFile))
            {
            case EOF:
                return read_count;
            case ' ':
                column_count++;
                read_count++;
                break;
            case '\r':
                if (fgetc(pFile) == '\n')
                {
                    read_count += 2;
                    rol_count++;
                    column_count = 0;
                }
                else
                {
                    fseek(pFile, -2, SEEK_CUR);
                    return read_count;
                }
                break;
            case '\n':
                read_count++;
                rol_count++;
                column_count = 0;
                break;
            default:
                fseek(pFile, -1, SEEK_CUR);
                return read_count;
            }
        }
    };

    // 函数封装
    std::function<std::string(void)> Check_Object;
    std::function<std::string(void)> Check_Value;
    std::function<std::string(void)> Check_Arry;
    std::function<std::string(void)> Check_Pair;

    // 函数定义
    Check_Object = [&](void) -> std::string
    {
        Lambda_skip_blank();

        char ch_get = fgetc(pFile);
        if (ch_get != '{')
        {
            if (ch_get == EOF)
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            else
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'.";
        }
        column_count++;

        while (true)
        {
            Lambda_skip_blank();
            ch_get = fgetc(pFile);
            column_count++;

            switch (ch_get)
            {
            case '}':
                return std::string();
            case '\"':
                fseek(pFile, -1, SEEK_CUR);
                column_count--;
                {
                    std::string err_str = Check_Pair();
                    if (!err_str.empty())
                        return err_str;

                    // 结束后读取段
                    size_t now_rol_count = rol_count;
                    size_t now_column_count = column_count;

                    Lambda_skip_blank();
                    char ch_get = fgetc(pFile);
                    if ((ch_get != '}') && (ch_get != ','))
                    {
                        if (ch_get == ']')
                            return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing '}'.";
                        else if (ch_get == EOF)
                            return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
                        else
                            return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing comma.";
                    }
                    fseek(pFile, -1, SEEK_CUR);
                }
                break;
            case ',':
            {
                size_t now_rol_count = rol_count;
                size_t now_column_count = column_count;

                Lambda_skip_blank();

                if (fgetc(pFile) != '\"')
                    return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Unexpected ','.";
                fseek(pFile, -1, SEEK_CUR);
                break;
            }
            case EOF:
                return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            default:
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'.";
            }
        }
    };

    Check_Value = [&](void) -> std::string
    {
        Lambda_skip_blank();

        size_t begin_rol = rol_count;
        size_t begin_column = column_count;

        bool is_string = false;
        char ch_get = fgetc(pFile);

        // 判定第一个字符
        switch (ch_get)
        {
        case EOF:
            return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
        case '\"':
            is_string = true;
            break;
        case '{':
            fseek(pFile, -1, SEEK_CUR);
            return Check_Object();
        case '[':
            fseek(pFile, -1, SEEK_CUR);
            return Check_Arry();
        default:
            break;
        }

        // 判定为字符串
        if (is_string)
        {
            column_count++;
            while (true)
            {
                ch_get = fgetc(pFile);
                column_count++;
                switch (ch_get)
                {
                case '\"':
                    return std::string();
                case '\\': // 转义符
                    ch_get = fgetc(pFile);
                    if (ch_get != EOF)
                    {
                        column_count++;
                        continue;
                    }
                case EOF:
                    return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
                case '\n':
                    return std::string(path_to_file) + ':' + std::to_string(begin_rol) + ':' + std::to_string(begin_column) + ": Unfinished string.";
                default:
                    continue;
                }
            }
        }
        else
            fseek(pFile, -1, SEEK_CUR);

        // 识别有效数值

        std::string segment_read;
        while (true)
        {
            bool segment_finish = false;

            ch_get = fgetc(pFile);
            column_count++;
            switch (ch_get)
            {
            case '\r':
            case ',':
            case '}':
            case ']':
                column_count--;
                fseek(pFile, -1, SEEK_CUR);
            case EOF:
            case ' ':
            case '\n':
                segment_finish = true;
                break;
            default:
                segment_read += ch_get;
            }

            if (segment_finish)
                break;
        }

        if ((segment_read == "true") || (segment_read == "false") || (segment_read == "null"))
            return std::string();

        // 数值识别
        {
            char *end_ptr;
            strtod(segment_read.c_str(), &end_ptr);

            // 未被完全转化、出现先导0、先导+、尾缀小数点时非法
            if ((size_t(end_ptr - segment_read.c_str()) < segment_read.size()) || ((segment_read.c_str()[0] == '0') && (segment_read.size() > 1)) || (segment_read.c_str()[0] == '+') || end_ptr[-1] == '.')
                return std::string(path_to_file) + ':' + std::to_string(begin_rol) + ':' + std::to_string(begin_column) + ": Invalid value \"" + segment_read + "\".";
        }

        return std::string();
    };

    Check_Arry = [&](void) -> std::string
    {
        Lambda_skip_blank();

        char ch_get = fgetc(pFile);
        if (ch_get != '[')
        {
            if (ch_get == EOF)
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            else
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'.";
        }
        column_count++;

        while (true)
        {
            Lambda_skip_blank();
            ch_get = fgetc(pFile);
            column_count++;

            switch (ch_get)
            {
            case ']':
                return std::string();
            case ',':
            {
                size_t now_rol_count = rol_count;
                size_t now_column_count = column_count;

                Lambda_skip_blank();

                if (fgetc(pFile) == ']')
                    return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Unexpected ','.";
                fseek(pFile, -1, SEEK_CUR);
                break;
            }
            case EOF:
                return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            default:
            {
                column_count--;
                fseek(pFile, -1, SEEK_CUR);

                std::string err_str = Check_Value();
                if (!err_str.empty())
                    return err_str;

                // 结束后读取段
                size_t now_rol_count = rol_count;
                size_t now_column_count = column_count;

                Lambda_skip_blank();
                char ch_get = fgetc(pFile);

                if ((ch_get != ',') && (ch_get != ']'))
                {
                    if (ch_get == '}')
                        return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing ']'.";
                    else if (ch_get == EOF)
                        return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
                    else
                        return std::string(path_to_file) + ':' + std::to_string(now_rol_count) + ':' + std::to_string(now_column_count) + ": Missing comma.";
                }
                fseek(pFile, -1, SEEK_CUR);
            }
            }
        }
    };

    Check_Pair = [&](void) -> std::string
    {
        Lambda_skip_blank();

        char ch_get = fgetc(pFile);
        if (ch_get != '\"')
        {
            if (ch_get == EOF)
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            else
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'.";
        }
        column_count++;

        // 遍历下一个引号
        bool key_end = false;
        while (true)
        {
            ch_get = fgetc(pFile);
            column_count++;

            switch (ch_get)
            {
            case '\"':
                key_end = true;
                break;
            case '\n':
                rol_count++;
                column_count = 0;
                break;
            case EOF:
                return std::string(path_to_file) + ':' + std::to_string(rol_count - 1) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            }

            if (key_end)
                break;
        }

        // 寻找键值对标记
        Lambda_skip_blank();
        ch_get = fgetc(pFile);
        if (ch_get != ':')
        {
            if (ch_get == EOF)
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
            else
                return std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected '" + ch_get + "'. ':' is needed.";
        }
        column_count++;

        return Check_Value();
    };

    // 跳过空白检查第一个字符
    Lambda_skip_blank();
    switch (fgetc(pFile))
    {
    case '[':
        fseek(pFile, -1, SEEK_CUR);
        err_str = Check_Arry();
        break;
    case '{':
        fseek(pFile, -1, SEEK_CUR);
        err_str = Check_Object();
        break;
    case EOF:
        err_str = std::string(path_to_file) + ':' + std::to_string(rol_count) + ':' + std::to_string(column_count) + ": Unexpected EOF.";
        break;
    default:
        fseek(pFile, -1, SEEK_CUR);
        err_str = Check_Value();
    }

    // 关闭文件
    fclose(pFile);
    return err_str;
}

/**
 * @brief 解析Json文件
 * @param path_to_file 文件路径串
 * @param pJson_Value Value 指针
 * @return std::string 错误值
 */
std::string JsonFile_Parse(const char *path_to_file, Json_Value *pJson_Value)
{
    // 存在格式错误时返回NULL值,通过格式检查时信任后续的输入
    std::string err_str = JsonFile_FormatCheck(path_to_file);
    if (!err_str.empty())
        return err_str;

    // 检查空指针
    if (pJson_Value == nullptr)
        return "Null container ptr.";

    // 打开已完成检查的文件
    FILE *pFile = fopen(path_to_file, "rb");

    // 跳过空白部分 return -> skip count
    auto Lambda_skip_blank = [&](void) -> size_t
    {
        size_t read_count = 0;
        while (true)
        {
            switch (fgetc(pFile))
            {
            case EOF:
                return read_count;
            case ' ':
                read_count++;
                break;
            case '\r':
                if (fgetc(pFile) == '\n')
                {
                    read_count += 2;
                }
                else
                {
                    fseek(pFile, -2, SEEK_CUR);
                    return read_count;
                }
                break;
            case '\n':
                read_count++;
                break;
            default:
                fseek(pFile, -1, SEEK_CUR);
                return read_count;
            }
        }
    };

    // 函数封装
    std::function<Json_Object(void)> Parse_Object;
    std::function<Json_Value(void)> Parse_Value;
    std::function<Json_Arry(void)> Parse_Arry;
    std::function<Json_Pair(void)> Parse_Pair;

    // 函数定义
    Parse_Object = [&](void) -> Json_Object
    {
        Json_Object temp_obj;
        Lambda_skip_blank();

        // 拿掉第一个 '{'
        char ch_get = fgetc(pFile);

        while (true)
        {
            Lambda_skip_blank();
            ch_get = fgetc(pFile);

            switch (ch_get)
            {
            case '}':
                return temp_obj;
            case '\"':
                fseek(pFile, -1, SEEK_CUR);
                {
                    std::vector<Json_Pair> pair_list = temp_obj.element_list;
                    pair_list.push_back(Parse_Pair());
                    temp_obj = Json_Object(pair_list);
                }
                break;
            default:
                break;
            }
        }
    };

    Parse_Value = [&](void) -> Json_Value
    {
        Lambda_skip_blank();

        bool is_string = false;
        char ch_get = fgetc(pFile);

        // 判定第一个字符
        switch (ch_get)
        {
        case '\"':
            is_string = true;
            break;
        case '{':
            fseek(pFile, -1, SEEK_CUR);
            return Parse_Object();
        case '[':
            fseek(pFile, -1, SEEK_CUR);
            return Parse_Arry();
        default:
            break;
        }

        // 判定为字符串
        if (is_string)
        {
            std::string value_str;
            while (true)
            {
                ch_get = fgetc(pFile);

                switch (ch_get)
                {
                case '\"':
                    return value_str;
                case '\\': // 转义符
                    ch_get = fgetc(pFile);
                    value_str.push_back('\\');
                    value_str.push_back(ch_get);
                    break;
                default:
                    value_str.push_back(ch_get);
                    continue;
                }
            }
        }
        else
            fseek(pFile, -1, SEEK_CUR);

        // 识别非字符串类型Json值
        std::string segment_read;
        while (true)
        {
            bool segment_finish = false;

            ch_get = fgetc(pFile);
            switch (ch_get)
            {
            case '\r':
            case ',':
            case '}':
            case ']':
                fseek(pFile, -1, SEEK_CUR);
            case EOF:
            case ' ':
            case '\n':
                segment_finish = true;
                break;
            default:
                segment_read += ch_get;
            }

            if (segment_finish)
                break;
        }

        // 逻辑值识别
        if (segment_read == "true")
            return true;
        if (segment_read == "false")
            return false;
        if (segment_read == "null")
            return Json_Value();

        // 数值识别
        if (strstr(segment_read.c_str(), "e") || strstr(segment_read.c_str(), "."))
            return strtod(segment_read.c_str(), nullptr);
        else
            return strtoll(segment_read.c_str(), nullptr, 0);
    };

    Parse_Arry = [&](void) -> Json_Arry
    {
        Lambda_skip_blank();

        // 拿掉第一个 '['
        char ch_get = fgetc(pFile);

        std::vector<Json_Value> value_list;
        while (true)
        {
            Lambda_skip_blank();
            ch_get = fgetc(pFile);

            switch (ch_get)
            {
            case ']':
                return value_list;
            case ',':
                break;
            default:
                fseek(pFile, -1, SEEK_CUR);
                value_list.push_back(Parse_Value());
            }
        }
    };

    Parse_Pair = [&](void) -> Json_Pair
    {
        std::string key_str;
        Lambda_skip_blank();

        // 拿掉第一个 '\"'
        char ch_get = fgetc(pFile);

        // 遍历下一个引号
        bool key_end = false;
        while (true)
        {
            ch_get = fgetc(pFile);

            switch (ch_get)
            {
            case '\"':
                key_end = true;
                break;
            default:
                key_str.push_back(ch_get);
                break;
            }

            if (key_end)
                break;
        }

        // 拿掉键值对标记
        Lambda_skip_blank();
        ch_get = fgetc(pFile);

        // 返回键值对
        return Json_Pair(key_str, Parse_Value());
    };

    // 跳过空白检查第一个字符
    Lambda_skip_blank();
    switch (fgetc(pFile))
    {
    case '[':
        fseek(pFile, -1, SEEK_CUR);
        *pJson_Value = Parse_Arry();
        break;
    case '{':
        fseek(pFile, -1, SEEK_CUR);
        *pJson_Value = Parse_Object();
        break;
    default:
        fseek(pFile, -1, SEEK_CUR);
        *pJson_Value = Parse_Value();
        break;
    }

    fclose(pFile);
    return std::string();
}

/**
 * @brief Json对象保存
 * @param path_to_file 文件路径串
 * @param value Json Value
 * @param enable_pretty_print 启用美观打印
 * @return std::string 错误值
 */
std::string Json_Export(const char *path_to_file, Json_Value value, bool enable_pretty_print)
{
    // 打开文件
    FILE *pFile = fopen(path_to_file, "wb");
    if (pFile == nullptr)
    {
        fclose(pFile);
        return "file \"" + std::string(path_to_file) + "\" open failed.";
    }
    // 函数封装
    std::function<void(const Json_Object &, size_t, bool)> Export_Object;
    std::function<void(const Json_Value &, size_t, bool)> Export_Value;
    std::function<void(const Json_Arry &, size_t, bool)> Export_Arry;
    std::function<void(const Json_Pair &, size_t)> Export_Pair;

    // 函数定义
    Export_Object = [&](const Json_Object &obj, size_t depth, bool first_line_indent)
    {
        // 首行缩进
        if (enable_pretty_print && first_line_indent)
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");

        // 对象起始
        fprintf(pFile, "{");
        if (enable_pretty_print && (!obj.isEmpty()))
            fprintf(pFile, "\r\n");

        // 输出键值对
        for (auto pair : obj.element_list)
        {
            Export_Pair(pair, depth + 1);
            fprintf(pFile, enable_pretty_print ? ",\r\n" : ",");
        }
        if (!obj.isEmpty())
        {
            fseek(pFile, enable_pretty_print ? -3 : -1, SEEK_CUR);
            if (enable_pretty_print)
                fprintf(pFile, "\r\n");
        }

        // 尾部缩进
        if (enable_pretty_print && (!obj.isEmpty()))
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");

        // 对象结束
        fprintf(pFile, "}");
    };

    Export_Value = [&](const Json_Value &value, size_t depth, bool indent)
    {
        if (enable_pretty_print && indent)
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");
        switch (value.type)
        {
        case Json_Value::TYPE_NULL: // 空值
            fprintf(pFile, "null");
            break;
        case Json_Value::TYPE_STR: // 字符串
            fprintf(pFile, "\"%s\"", value.asString().c_str());
            break;
        case Json_Value::TYPE_ARRY: // 数组
            Export_Arry(value.asArry(), depth, false);
            break;
        case Json_Value::TYPE_OBJ: // 对象
            Export_Object(value.asObject(), depth, false);
            break;
        case Json_Value::TYPE_NUM_INTEGER: // 整数常数
            fprintf(pFile, "%lld", value.asInteger());
            break;
        case Json_Value::TYPE_NUM_FLOAT: // 浮点常数
            fprintf(pFile, "%e", value.asFloat());
            break;
        case Json_Value::TYPE_BOOLEAN: // 布尔逻辑值
            if (value.asBoolean() == true)
                fprintf(pFile, "true");
            else
                fprintf(pFile, "false");
        }
    };

    Export_Pair = [&](const Json_Pair &pair, size_t depth)
    {
        if (enable_pretty_print)
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");

        fprintf(pFile, "\"%s\":", pair.key.c_str());
        if (enable_pretty_print)
            fprintf(pFile, " ");
        Export_Value(pair.value, depth, false);
    };

    Export_Arry = [&](const Json_Arry &arry, size_t depth, bool first_line_indent)
    {
        // 首行缩进
        if (enable_pretty_print && first_line_indent)
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");

        // 数组起始
        fprintf(pFile, "[");
        if (enable_pretty_print && (!arry.isEmpty()))
            fprintf(pFile, "\r\n");

        // 输出数组数值
        for (auto value : arry.element_list)
        {
            Export_Value(value, depth + 1, true);
            fprintf(pFile, enable_pretty_print ? ",\r\n" : ",");
        }
        if (!arry.isEmpty())
        {
            fseek(pFile, enable_pretty_print ? -3 : -1, SEEK_CUR);
            if (enable_pretty_print)
                fprintf(pFile, "\r\n");
        }
        // 尾部缩进
        if (enable_pretty_print && (!arry.isEmpty()))
            for (size_t count = 0; count < depth; count++)
                fprintf(pFile, "    ");

        // 对象结束
        fprintf(pFile, "]");
    };

    if (value.type == Json_Value::TYPE_OBJ)
        Export_Object(value.asObject(), 0, false);
    else if (value.type == Json_Value::TYPE_ARRY)
        Export_Arry(value.asArry(), 0, false);
    else
        Export_Value(value, 0, false);

    fclose(pFile);
    return std::string();
}

// std::string 构造
Json_Value::Json_Value(std::string str) : private_type(TYPE_STR), p_mem(malloc(sizeof(str)))
{
    if (p_mem != nullptr)
        new (p_mem) std::string(str);
    else
        this->private_type = TYPE_NULL;
}

// Json_Arry 构造
Json_Value::Json_Value(Json_Arry arry) : private_type(TYPE_ARRY), p_mem(malloc(sizeof(arry)))
{
    if (p_mem != nullptr)
        new (p_mem) Json_Arry(arry);
    else
        this->private_type = TYPE_NULL;
}

// Json_Object 构造
Json_Value::Json_Value(Json_Object object) : private_type(TYPE_OBJ), p_mem(malloc(sizeof(object)))
{
    if (p_mem != nullptr)
        new (p_mem) Json_Object(object);
    else
        this->private_type = TYPE_NULL;
}

// 整数值 构造
Json_Value::Json_Value(int64_t num_integer) : private_type(TYPE_NUM_INTEGER), p_mem(malloc(sizeof(num_integer)))
{
    if (p_mem != nullptr)
        *(decltype(num_integer) *)p_mem = num_integer;
    else
        this->private_type = TYPE_NULL;
}

// 浮点值 构造
Json_Value::Json_Value(double num_float) : private_type(TYPE_NUM_FLOAT), p_mem(malloc(sizeof(num_float)))
{
    if (p_mem != nullptr)
        *(decltype(num_float) *)p_mem = num_float;
    else
        this->private_type = TYPE_NULL;
}

// Boolean 逻辑值构造
Json_Value::Json_Value(bool boolean) : private_type(TYPE_BOOLEAN), p_mem(malloc(sizeof(boolean)))
{
    if (p_mem != nullptr)
        *(decltype(boolean) *)p_mem = boolean;
    else
        this->private_type = TYPE_NULL;
}

// 浅拷贝构造
Json_Value::Json_Value(const Json_Value &temp) : private_type(TYPE_NULL), p_mem(nullptr)
{
    // 执行深拷贝
    *this = temp;
}

// 深拷贝
Json_Value &Json_Value::operator=(const Json_Value &another)
{
    if (this != &another)
    {
        // 先析构释放内存
        this->~Json_Value();

        // 重新赋值
        this->private_type = another.type;
        switch (another.type)
        {
        case TYPE_STR:
            this->p_mem = malloc(sizeof(std::string));
            if (this->p_mem != nullptr)
            {
                new (this->p_mem) std::string();
                *((std::string *)this->p_mem) = *((std::string *)another.p_mem);
            }
            break;
        case TYPE_ARRY:
            this->p_mem = malloc(sizeof(Json_Arry));
            if (this->p_mem != nullptr)
            {
                new (this->p_mem) Json_Arry();
                *((Json_Arry *)this->p_mem) = *((Json_Arry *)another.p_mem);
            }
            break;
        case TYPE_OBJ:
            this->p_mem = malloc(sizeof(Json_Object));
            if (this->p_mem != nullptr)
            {
                new (this->p_mem) Json_Object();
                *((Json_Object *)this->p_mem) = *((Json_Object *)another.p_mem);
            }
            break;
        case TYPE_NUM_INTEGER:
            this->p_mem = malloc(sizeof(int64_t));
            if (this->p_mem != nullptr)
                *((int64_t *)this->p_mem) = *((int64_t *)another.p_mem);
            break;
        case TYPE_NUM_FLOAT:
            this->p_mem = malloc(sizeof(double));
            if (this->p_mem != nullptr)
                *((double *)this->p_mem) = *((double *)another.p_mem);
            break;
        case TYPE_BOOLEAN:
            this->p_mem = malloc(sizeof(bool));
            if (this->p_mem != nullptr)
                *((bool *)this->p_mem) = *((bool *)another.p_mem);
            break;
        default:
            this->p_mem = nullptr;
        }
    }

    return *this;
}

// 析构
Json_Value::~Json_Value()
{
    if (this->p_mem != nullptr)
    {
        // 对象析构
        switch (this->private_type)
        {
        case TYPE_STR:
            ((std::string *)p_mem)->~basic_string();
            break;
        case TYPE_ARRY:
            ((Json_Arry *)p_mem)->~Json_Arry();
            break;
        case TYPE_OBJ:
            ((Json_Object *)p_mem)->~Json_Object();
            break;
        default:
            break;
        };

        // 释放内存
        free(p_mem);
    }
    this->private_type = TYPE_NULL;
}

// 作为直接值获取
std::string Json_Value::asString(void) const
{
    if (this->type == TYPE_STR)
        return *(std::string *)this->p_mem;
    else
        return std::string("");
}

// 作为 Json_Arry 获取
Json_Arry Json_Value::asArry(void) const
{
    if (this->type == TYPE_ARRY)
        return *(Json_Arry *)this->p_mem;
    else
        return Json_Arry();
}

// 作为 Json_Object 获取
Json_Object Json_Value::asObject(void) const
{
    if (this->type == TYPE_OBJ)
        return *(Json_Object *)this->p_mem;
    else
        return Json_Object();
}

// 作为 int64 获取
int64_t Json_Value::asInteger(void) const
{
    if (this->type == TYPE_NUM_INTEGER)
        return *(int64_t *)this->p_mem;
    else
        return 0;
}

// 作为 double 获取
double Json_Value::asFloat(void) const
{
    if (this->type == TYPE_NUM_FLOAT)
        return *(double *)this->p_mem;
    else
        return 0;
}

// 作为 Boolean 逻辑值获取
bool Json_Value::asBoolean(void) const
{
    if (this->type == TYPE_BOOLEAN)
        return *(bool *)this->p_mem;
    else
        return 0;
}

// 是否为空
bool Json_Value::isNull(void) const
{
    return (this->private_type == TYPE_NULL);
}

// =================================================================================================

// 浅拷贝构造
Json_Pair::Json_Pair(const Json_Pair &temp)
{
    *this = temp;
}

// 深拷贝
Json_Pair &Json_Pair::operator=(const Json_Pair &another)
{
    if (this != &another)
    {
        this->private_key_str = another.private_key_str;
        this->private_value = another.private_value;
    }

    return *this;
}

// =================================================================================================

// 浅拷贝构造
Json_Arry::Json_Arry(const Json_Arry &temp)
{
    // 执行深拷贝
    *this = temp;
}

// 深拷贝
Json_Arry &Json_Arry::operator=(const Json_Arry &another)
{
    if (this != &another)
    {
        this->private_element_list = another.private_element_list;
    }

    return *this;
}

// 获取元素大小
size_t Json_Arry::size(void) const
{
    return this->private_element_list.size();
}

// 数组索引重载
Json_Value Json_Arry::operator[](size_t index) const
{
    if (index < this->private_element_list.size())
        return this->private_element_list[index];
    else
        return Json_Value();
}

// 是否为空
bool Json_Arry::isEmpty(void) const
{
    return (this->private_element_list.size() == 0);
}

// =================================================================================================

// 浅拷贝构造
Json_Object::Json_Object(const Json_Object &temp)
{
    // 执行深拷贝
    *this = temp;
}

// 深拷贝
Json_Object &Json_Object::operator=(const Json_Object &another)
{
    if (this != &another)
    {
        this->private_element_list = another.private_element_list;
    }

    return *this;
}

// 获取元素大小
size_t Json_Object::size(void) const
{
    return this->private_element_list.size();
}

// 数组索引重载
Json_Pair Json_Object::operator[](size_t index) const
{
    if (index < this->private_element_list.size())
        return this->private_element_list[index];
    else
        return Json_Pair();
}

// 由Key 查找值
Json_Value Json_Object::get(std::string key) const
{
    for (auto pair : this->private_element_list)
        if (pair.key == key)
            return pair.value;

    return Json_Value();
}

// 是否为空
bool Json_Object::isEmpty(void) const
{
    return (this->private_element_list.size() == 0);
}