#include "Tool.h"
#include <string.h>
#include <chrono>
#include <ctime>
using namespace std;

Tool::Tool(/* args */)
{
}

Tool::~Tool()
{
}

int Tool::ByteLittleToInt(unsigned char *Count)
{
    int int1 = Count[0] & 0xff;
    int int2 = (Count[1] & 0xff) << 8;
    int int3 = (Count[2] & 0xff) << 16;
    int int4 = (Count[3] & 0xff) << 24;

    return int1 | int2 | int3 | int4;
}

void Tool::Error(std::string O)
{
#ifdef Development_mode
    std::cout << "\n----[ERROR]----\n";
    std::cout << "\n----[By "
              << "YosinLenheart"
              << "]----\n";
    std::cout << O << std::endl;
    std::cout << "\n----------------\n";
#endif
}
void Tool::Warring(std::string W)
{
#ifdef Development_mode
    std::cout << "\n----[WARRING]----\n";
    std::cout << "\n----[By "
              << "YosinLenheart"
              << "]----\n";
    std::cout << W << std::endl;
    std::cout << "\n----------------\n";
#endif
}
void Tool::Logger(std::string L)
{
#ifdef Development_mode
    std::cout << "\n----[LOGGER]----\n";
    std::cout << "\n----[By "
              << "YosinLenheart"
              << "]----\n";
    std::cout << L << std::endl;
    std::cout << "\n----------------\n";
#endif
}

void Tool::Split(const std::string &src, std::vector<std::string> &dest, const std::string &separator)
{
    std::string str = src;
    std::string substring;
    std::string::size_type start = 0, index;
    dest.clear();
    index = str.find_first_of(separator, start);
    do
    {
        if (index != std::string::npos)
        {
            substring = str.substr(start, index - start);
            dest.push_back(substring);
            start = index + separator.size();
            index = str.find(separator, start);
            if (start == std::string::npos)
                break;
        }
    } while (index != std::string::npos);

    // the last part
    substring = str.substr(start);
    dest.push_back(substring);
}

long long Tool::get_cur_time()
{
    // 获取操作系统当前时间点（精确到微秒）
    chrono::time_point<chrono::system_clock, chrono::microseconds> tpMicro = chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now());
    // (微秒精度的)时间点 => (微秒精度的)时间戳
    time_t totalMicroSeconds = tpMicro.time_since_epoch().count();

    long long currentTime = ((long long)totalMicroSeconds) / 1000;

    return currentTime;
}

// int Tool::UTF8ToGB2312(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
// {
//     iconv_t cd = iconv_open("gb2312//IGNORE", "utf-8//IGNORE"); // take care of "//IGNORE", it will ignore those invalid code
//     if (0 == cd)
//         return -2;
//     memset(szDst, 0, iDstLen);
//     char **src = &szSrc;
//     char **dst = &szDst;
//     if (-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
//         return -1;
//     iconv_close(cd);
//     return 0;
// }
// int Tool::GB2312ToUTF8(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
// {
//     iconv_t cd = iconv_open("utf-8//IGNORE", "gb2312//IGNORE");
//     if (0 == cd)
//         return -2;
//     memset(szDst, 0, iDstLen);
//     char **src = &szSrc;
//     char **dst = &szDst;
//     if (-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
//         return -1;
//     iconv_close(cd);
//     return 0;
// }

int Tool::UTF8ToGB2312(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
{
    iconv_t cd = iconv_open("gb2312//IGNORE", "utf-8//IGNORE");
    if (cd == (iconv_t)-1) // 修正判断条件
        return -2;

    memset(szDst, 0, iDstLen);

    // 复制指针和长度，避免修改原始参数
    char *src_ptr = szSrc;
    char *dst_ptr = szDst;
    size_t src_left = iSrcLen;
    size_t dst_left = iDstLen;

    // 保存原始指针用于计算转换后的长度
    const char *src_start = src_ptr;
    char *dst_start = dst_ptr;

    // 执行转换
    if (iconv(cd, &src_ptr, &src_left, &dst_ptr, &dst_left) == (size_t)-1)
    {
        int err = errno;
        iconv_close(cd); // 确保关闭转换描述符

        // 根据不同错误返回不同错误码
        switch (err)
        {
        case E2BIG:
            return -3; // 目标缓冲区不足
        case EILSEQ:
            return -4; // 非法字符序列
        case EINVAL:
            return -5; // 不完整的多字节序列
        default:
            return -1; // 其他错误
        }
    }

    // 关闭转换描述符
    iconv_close(cd);

    // 返回转换后的字符串长度（不包括终止符）
    return dst_ptr - dst_start;
}

int Tool::GB2312ToUTF8(char *szSrc, size_t iSrcLen, char *szDst, size_t iDstLen)
{
    // 逻辑与UTF8ToGB2312完全相同，只是字符编码相反
    iconv_t cd = iconv_open("utf-8//IGNORE", "gb2312//IGNORE");
    if (cd == (iconv_t)-1)
        return -2;

    memset(szDst, 0, iDstLen);

    char *src_ptr = szSrc;
    char *dst_ptr = szDst;
    size_t src_left = iSrcLen;
    size_t dst_left = iDstLen;

    const char *src_start = src_ptr;
    char *dst_start = dst_ptr;

    if (iconv(cd, &src_ptr, &src_left, &dst_ptr, &dst_left) == (size_t)-1)
    {
        int err = errno;
        iconv_close(cd);

        switch (err)
        {
        case E2BIG:
            return -3;
        case EILSEQ:
            return -4;
        case EINVAL:
            return -5;
        default:
            return -1;
        }
    }

    iconv_close(cd);
    return dst_ptr - dst_start;
}