/**
  ******************************************************************************
  * @file           : Network.cpp
  * @author         : Dream
  * @brief          : None
  * @attention      : None
  * @date           : 24-10-3
  ******************************************************************************
  */

#include "Network.hpp"
#include <curl/curl.h>
#include <iostream>
#include <chrono>
#include <format>
#include <vector>

#include "log.hpp"
#include "../../include/obfuscate.hpp"
// CURL 回调函数
size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
    reinterpret_cast<std::string *>(userp)->append(reinterpret_cast<char *>(contents), size * nmemb);
    return size * nmemb;
}

// 发送 POST 请求
std::string Network::post_request(const std::string& url, const std::string& postdata) {
    CURL* curl = curl_easy_init();
    std::string response_string;

    if (!curl) {
        char* log =  AY_OBFUSCATE("Failed to initialize CURL");
        LOG_DEBUG("%s",log);
        return response_string;
    }

    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, AY_OBFUSCATE("Content-Type: application/x-www-form-urlencoded"));
    if (!headers) {
        char* log =  AY_OBFUSCATE("Failed to append headers");
        LOG_DEBUG("%s",log);
        curl_easy_cleanup(curl);
        return response_string;
    }

    // 设置 curl 选项
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string);
    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L); // 请求总超时 30 秒
    curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L); // 连接超时 10 秒
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 支持重定向
#ifdef DEBUG_LOG
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // 禁用 SSL 验证（调试用，生产慎用）
#endif
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "Angel/1.0 (Android)"); // 设置 User-Agent

    // 调试日志
#ifdef DEBUG_LOG
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    char curl_error_buffer[CURL_ERROR_SIZE] = {0};
    curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_error_buffer);
#endif

    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
        LOG_DEBUG(AY_OBFUSCATE("curl_easy_perform() failed: %s"), curl_easy_strerror(res));
#ifdef DEBUG_LOG
        if (curl_error_buffer[0]) {
            LOG_DEBUG(AY_OBFUSCATE("CURL error details: %s"), curl_error_buffer);
        }
#endif
    }

    curl_slist_free_all(headers);
    curl_easy_cleanup(curl);
    return response_string;
}

static const std::string custom_base64_chars{AY_OBFUSCATE("wvWHT/3d4VnFzYMkXqtoZLRuIC0KxySspEUJc8DarG596hibB1lgfNe+jAm7OP2Q")};
static const std::string custom_base64_chars_2{AY_OBFUSCATE("e+Tr9JxRiypVHAFSo7cnP2wN3auXkMd0ZKIbsl5WCGEhfQqBUvLmO/tzY4681Djg")};
static const std::string base64_chars{AY_OBFUSCATE("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")};

std::string Network::custom_base64_decode(const std::string &encoded_string) {
    std::vector<int> decoding_table(256, -1);
    for (size_t i = 0; i < custom_base64_chars.size(); i++) {
        decoding_table[static_cast<unsigned char>(custom_base64_chars[i])] = i;
    }

    std::string decoded_string;
    int val = 0;
    int valb = -8;
    for (char c: encoded_string) {
        if (decoding_table[c] == -1) break;
        val = (val << 6) + decoding_table[c];
        valb += 6;
        if (valb >= 0) {
            decoded_string.push_back(static_cast<char>((val >> valb) & 0xFF));
            valb -= 8;
        }
    }
    return decoded_string;
}

std::string Network::custom_base64_decode_2(const std::string &encoded_string) {
    std::vector<int> decoding_table(256, -1);
    for (size_t i = 0; i < custom_base64_chars_2.size(); i++) {
        decoding_table[static_cast<unsigned char>(custom_base64_chars_2[i])] = i;
    }

    std::string decoded_string;
    int val = 0;
    int valb = -8;
    for (char c: encoded_string) {
        if (decoding_table[c] == -1) break;
        val = (val << 6) + decoding_table[c];
        valb += 6;
        if (valb >= 0) {
            decoded_string.push_back(static_cast<char>((val >> valb) & 0xFF));
            valb -= 8;
        }
    }
    return decoded_string;
}

std::string Network::base64_decode(const std::string &encoded_string) {
    std::vector<int> decoding_table(256, -1);
    for (size_t i = 0; i < base64_chars.size(); i++) {
        decoding_table[static_cast<unsigned char>(base64_chars[i])] = i;
    }

    std::string decoded_string;
    int val = 0;
    int valb = -8;
    for (char c: encoded_string) {
        if (decoding_table[c] == -1) break;
        val = (val << 6) + decoding_table[c];
        valb += 6;
        if (valb >= 0) {
            decoded_string.push_back(static_cast<char>((val >> valb) & 0xFF));
            valb -= 8;
        }
    }
    return decoded_string;
}

#define BOX_LEN 256

// 辅助函数，用于交换两个字节的值
static void swap_byte(unsigned char *a, unsigned char *b) {
    unsigned char swapByte = *a;
    *a = *b;
    *b = swapByte;
}

std::string Network::RC4Decrypt(const std::string &encrypted_data, const std::string &key) {
    if (encrypted_data.empty() || key.empty()) {
        return "";
    }

    const int data_len = encrypted_data.size();
    const int key_len = key.size();

    unsigned char mBox[BOX_LEN];
    for (int i = 0; i < BOX_LEN; i++) {
        mBox[i] = i;
    }

    int j = 0;
    for (int i = 0; i < BOX_LEN; i++) {
        j = (j + mBox[i] + key[i % key_len]) % BOX_LEN;
        swap_byte(&mBox[i], &mBox[j]);
    }

    std::string decrypted_data;
    decrypted_data.resize(data_len);
    int x = 0, y = 0;

    for (int k = 0; k < data_len; k++) {
        x = (x + 1) % BOX_LEN;
        y = (y + mBox[x]) % BOX_LEN;
        swap_byte(&mBox[x], &mBox[y]);
        decrypted_data[k] = encrypted_data[k] ^ mBox[(mBox[x] + mBox[y]) % BOX_LEN];
    }

    return decrypted_data;
}
