#pragma clang diagnostic push
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
#pragma once
#include <cstdint>
#include <ctime>
#include <cstring>
#ifndef HEADER_JNI_H_
#define HEADER_JNI_H_
#include <jni.h>
#endif
#ifndef HEADER_P_H_
#define HEADER_P_H_
#include "guard/JByteArrayGuard.cpp"
#endif
#include <string>

// 字节序转换宏（跨平台）
#pragma clang diagnostic push
#pragma ide diagnostic ignored "UnreachableCallsOfFunction"
#if defined(_WIN32)
#include <winsock2.h>
#pragma commen+t(lib, "ws2_32.lib")

#define htobe32(x) htonl(x)
#define be32toh(x) ntohl(x)
#define htobe16(x) htons(x)
#define be16toh(x) ntohs(x)

// Windows下64位字节序转换需要自己实现
static inline uint64_t htobe64(uint64_t x) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    return ((uint64_t)htonl(x & 0xFFFFFFFF) << 32) | htonl(x >> 32);
#else
    return x;
#endif
}

static inline uint64_t be64toh(uint64_t x) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    return ((uint64_t)ntohl(x & 0xFFFFFFFF) << 32) | ntohl(x >> 32);
#else
    return x;
#endif
}

#elif defined(__APPLE__) || defined(__FreeBSD__)
#include <libkern/OSByteOrder.h>
    #define htobe32(x) OSSwapHostToBigInt32(x)
    #define be32toh(x) OSSwapBigToHostInt32(x)
    #define htobe16(x) OSSwapHostToBigInt16(x)
    #define be16toh(x) OSSwapBigToHostInt16(x)
    #define htobe64(x) OSSwapHostToBigInt64(x)
    #define be64toh(x) OSSwapBigToHostInt64(x)

#elif defined(__linux__) || defined(__ANDROID__)
    #include <endian.h>
    // Linux下endian.h已经定义了这些宏

#else
    // 通用实现
    #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
        // GCC/Clang内置函数
        #define htobe32(x) __builtin_bswap32(x)
        #define be32toh(x) __builtin_bswap32(x)
        #define htobe16(x) __builtin_bswap16(x)
        #define be16toh(x) __builtin_bswap16(x)
        #define htobe64(x) __builtin_bswap64(x)
        #define be64toh(x) __builtin_bswap64(x)
    #else
        #define htobe32(x) (x)
        #define be32toh(x) (x)
        #define htobe16(x) (x)
        #define be16toh(x) (x)
        #define htobe64(x) (x)
        #define be64toh(x) (x)
    #endif
#endif

// 手动字节序转换函数（备用）
static inline uint64_t manual_htobe64(uint64_t x) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    return ((uint64_t)__builtin_bswap32(x & 0xFFFFFFFF) << 32) | __builtin_bswap32(x >> 32);
#else
    return x;
#endif
}

static inline uint64_t manual_be64toh(uint64_t x) {
    return manual_htobe64(x);  // 对称操作
}

namespace EnhancedEncryptionMagic {
    // 主魔数：0x4C494233 (ASCII: "LIB3")
    static const uint32_t MAGIC = 0x4C494233;  // "LIB3" in hex

    // 文件头结构 - 调整为实际大小
    struct EnhancedFileHeader {
        uint32_t magic;           // 魔数: 0x4C494233 "LIB3" (4字节)
        uint16_t version_major;   // 主版本号 (2字节)
        uint16_t version_minor;   // 次版本号 (2字节)
        uint32_t flags;           // 标志位 (4字节)
        uint32_t original_size;   // 原始数据大小 (4字节)
        uint32_t encrypted_size;  // 加密数据大小 (4字节)
        uint64_t timestamp;       // 时间戳 (8字节)
        uint32_t checksum;        // 校验和 (4字节)
        uint32_t reserved;        // 保留字段 (4字节)
        // 总计: 4+2+2+4+4+4+8+4+4 = 36字节

        // 编译器可能添加4字节填充到40字节，但我们应该按36字节处理
    };

    // 计算实际结构体大小
    static const size_t CALCULATED_HEADER_SIZE =
            sizeof(uint32_t) +    // magic
            sizeof(uint16_t) +    // version_major
            sizeof(uint16_t) +    // version_minor
            sizeof(uint32_t) +    // flags
            sizeof(uint32_t) +    // original_size
            sizeof(uint32_t) +    // encrypted_size
            sizeof(uint64_t) +    // timestamp
            sizeof(uint32_t) +    // checksum
            sizeof(uint32_t);     // reserved

    static const size_t HEADER_SIZE = CALCULATED_HEADER_SIZE;

    // 标志位定义
    namespace Flags {
        static const uint32_t COMPRESSED = 0x00000001;  // 是否压缩
        static const uint32_t SIGNED     = 0x00000002;  // 是否签名
        static const uint32_t ENCRYPTED  = 0x00000004;  // 是否加密
        static const uint32_t VALIDATED  = 0x00000008;  // 是否验证
    };

    // 创建文件头
    static inline EnhancedFileHeader createHeader(uint32_t originalSize, uint32_t encryptedSize) {
        EnhancedFileHeader header;
        memset(&header, 0, sizeof(header));  // 清零初始化

        header.magic = MAGIC;
        header.version_major = 1;
        header.version_minor = 0;
        header.flags = Flags::ENCRYPTED;
        header.original_size = originalSize;
        header.encrypted_size = encryptedSize;
        header.timestamp = static_cast<uint64_t>(time(nullptr));
        header.checksum = 0;  // 将在之后计算
        header.reserved = 0;

        return header;
    }

    // 字节序安全的内存复制函数
    static inline void writeUint32(jbyte* buffer, uint32_t value, size_t offset) {
        uint32_t networkValue = htobe32(value);
        memcpy(buffer + offset, &networkValue, sizeof(uint32_t));
    }

    static inline void writeUint16(jbyte* buffer, uint16_t value, size_t offset) {
        uint16_t networkValue = htobe16(value);
        memcpy(buffer + offset, &networkValue, sizeof(uint16_t));
    }

    static inline void writeUint64(jbyte* buffer, uint64_t value, size_t offset) {
        uint64_t networkValue = htobe64(value);
        memcpy(buffer + offset, &networkValue, sizeof(uint64_t));
    }

    static inline uint32_t readUint32(const jbyte* buffer, size_t offset) {
        uint32_t networkValue;
        memcpy(&networkValue, buffer + offset, sizeof(uint32_t));
        return be32toh(networkValue);
    }

    static inline uint16_t readUint16(const jbyte* buffer, size_t offset) {
        uint16_t networkValue;
        memcpy(&networkValue, buffer + offset, sizeof(uint16_t));
        return be16toh(networkValue);
    }

    static inline uint64_t readUint64(const jbyte* buffer, size_t offset) {
        uint64_t networkValue;
        memcpy(&networkValue, buffer + offset, sizeof(uint64_t));
        return be64toh(networkValue);
    }

    // 验证文件头
    static inline bool validateHeader(const EnhancedFileHeader& header) {
        return header.magic == MAGIC &&
               header.version_major == 1 &&
               header.version_minor == 0 &&
               (header.flags & Flags::ENCRYPTED) != 0;
    }

    // 计算校验和（简单的CRC32替代）
    static inline uint32_t calculateChecksum(const jbyte* data, jsize length) {
        if (!data || length <= 0) {
            return 0;
        }

        uint32_t crc = 0xFFFFFFFF;
        const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);

        for (jsize i = 0; i < length; i++) {
            crc ^= bytes[i];
            for (int j = 0; j < 8; j++) {
                if (crc & 1) {
                    crc = (crc >> 1) ^ 0xEDB88320;
                } else {
                    crc = crc >> 1;
                }
            }
        }

        return ~crc;
    }

    // 更新文件头的校验和
    static inline void updateChecksum(EnhancedFileHeader& header, const jbyte* data, jsize length) {
        header.checksum = calculateChecksum(data, length);
    }

    // 验证数据校验和
    static inline bool verifyChecksum(const EnhancedFileHeader& header, const jbyte* data, jsize length) {
        uint32_t calculated = calculateChecksum(data, length);
        return header.checksum == calculated;
    }

    // 将文件头写入字节数组（使用网络字节序）
    static inline void writeHeaderToBytes(const EnhancedFileHeader& header, jbyte* buffer) {
        if (!buffer) return;

        size_t offset = 0;
        writeUint32(buffer, header.magic, offset); offset += 4;
        writeUint16(buffer, header.version_major, offset); offset += 2;
        writeUint16(buffer, header.version_minor, offset); offset += 2;
        writeUint32(buffer, header.flags, offset); offset += 4;
        writeUint32(buffer, header.original_size, offset); offset += 4;
        writeUint32(buffer, header.encrypted_size, offset); offset += 4;
        writeUint64(buffer, header.timestamp, offset); offset += 8;
        writeUint32(buffer, header.checksum, offset); offset += 4;
        writeUint32(buffer, header.reserved, offset); offset += 4;
    }

    // 从字节数组读取文件头
    static inline EnhancedFileHeader readHeaderFromBytes(const jbyte* buffer) {
        EnhancedFileHeader header{};
        memset(&header, 0, sizeof(header));

        if (!buffer) return header;

        size_t offset = 0;
        header.magic = readUint32(buffer, offset); offset += 4;
        header.version_major = readUint16(buffer, offset); offset += 2;
        header.version_minor = readUint16(buffer, offset); offset += 2;
        header.flags = readUint32(buffer, offset); offset += 4;
        header.original_size = readUint32(buffer, offset); offset += 4;
        header.encrypted_size = readUint32(buffer, offset); offset += 4;
        header.timestamp = readUint64(buffer, offset); offset += 8;
        header.checksum = readUint32(buffer, offset); offset += 4;
        header.reserved = readUint32(buffer, offset); offset += 4;

        return header;
    }

    // 将文件头格式化为可读字符串
    static inline std::string headerToString(const EnhancedFileHeader& header) {
        char magicStr[5] = {0};
        memcpy(magicStr, &header.magic, 4);

        char buffer[256];
        snprintf(buffer, sizeof(buffer),
                 "Magic: %s (0x%08X)\n"
                 "Version: %d.%d\n"
                 "Flags: 0x%08X\n"
                 "Original Size: %u bytes\n"
                 "Encrypted Size: %u bytes\n"
                 "Timestamp: %llu\n"
                 "Checksum: 0x%08X\n"
                 "Reserved: 0x%08X",
                 magicStr, header.magic,
                 header.version_major, header.version_minor,
                 header.flags,
                 header.original_size,
                 header.encrypted_size,
                 (unsigned long long)header.timestamp,
                 header.checksum,
                 header.reserved);

        return std::string(buffer);
    }

    // 验证文件是否完整
    static inline bool validateFileIntegrity(const EnhancedFileHeader& header,
                                             const jbyte* encryptedData,
                                             jsize encryptedDataSize) {
        // 检查大小是否匹配
        if (header.encrypted_size != encryptedDataSize) {
            return false;
        }

        // 检查校验和
        return verifyChecksum(header, encryptedData, encryptedDataSize);
    }

    // 加密函数指针类型
    typedef void (*EncryptFunc)(jbyte*, jsize, const char*, int);

    // 创建完整的加密文件
    static inline jbyteArray createEncryptedFile(JNIEnv* env,
                                                 const jbyte* originalData,
                                                 jsize originalSize,
                                                 const char* key,
                                                 size_t keyLen,
                                                 EncryptFunc encryptFunc) {

        if (!env || !originalData || originalSize <= 0 || !key || keyLen <= 0 || !encryptFunc) {
            return nullptr;
        }

        // 1. 创建加密数据数组
        jbyteArray encryptedDataArray = env->NewByteArray(originalSize);
        if (!encryptedDataArray) {
            return nullptr;
        }

        {
            // 使用局部作用域确保 encryptedDataGuard 在加密后释放
            JByteArrayGuard encryptedDataGuard(env, encryptedDataArray, false, JNI_ABORT);
            if (!encryptedDataGuard.isValid()) {
                env->DeleteLocalRef(encryptedDataArray);
                return nullptr;
            }

            // 复制并加密数据
            memcpy(encryptedDataGuard.get(), originalData, originalSize);
            encryptFunc(encryptedDataGuard.get(), originalSize, key, keyLen);

            // encryptedDataGuard 析构函数会自动以 JNI_ABORT 模式释放
        }

        // 注意：这里已经释放了加密数据，需要重新获取
        JByteArrayGuard encryptedDataGuard2(env, encryptedDataArray);
        if (!encryptedDataGuard2.isValid()) {
            env->DeleteLocalRef(encryptedDataArray);
            return nullptr;
        }

        // 2. 创建文件头
        EnhancedFileHeader header = createHeader(originalSize, originalSize);
        updateChecksum(header, encryptedDataGuard2.get(), originalSize);

        // 3. 创建最终结果
        jsize totalSize = HEADER_SIZE + originalSize;
        jbyteArray result = env->NewByteArray(totalSize);
        if (!result) {
            return nullptr;
        }

        JByteArrayGuard resultGuard(env, result);
        if (!resultGuard.isValid()) {
            env->DeleteLocalRef(result);
            return nullptr;
        }

        // 4. 写入数据
        writeHeaderToBytes(header, resultGuard.get());
        memcpy(resultGuard.get() + HEADER_SIZE, encryptedDataGuard2.get(), originalSize);

        // 5. 显式提交修改
        resultGuard.commit();  // 提交修改到 Java 端
        // resultGuard 析构时不会再释放

        // 6. 清理中间数组
        env->DeleteLocalRef(encryptedDataArray);

        return result;
    }

    // 从加密文件中提取数据
    static inline jbyteArray extractFromEncryptedFile(JNIEnv* env,
                                                      const jbyte* fileData,
                                                      jsize fileSize,
                                                      const char* key,
                                                      size_t keyLen,
                                                      EncryptFunc decryptFunc,
                                                      bool* isValid) {

        if (isValid) *isValid = false;

        if (!env || !fileData || fileSize < HEADER_SIZE || !key || keyLen <= 0 || !decryptFunc) {
            return nullptr;
        }

        // 读取文件头
        EnhancedFileHeader header = readHeaderFromBytes(fileData);

        // 验证文件头
        if (!validateHeader(header)) {
            return nullptr;
        }

        // 检查文件大小
        jsize expectedSize = HEADER_SIZE + header.encrypted_size;
        if (fileSize != expectedSize) {
            return nullptr;
        }

        // 提取加密数据
        const jbyte* encryptedData = fileData + HEADER_SIZE;

        // 验证完整性
        if (!validateFileIntegrity(header, encryptedData, header.encrypted_size)) {
            return nullptr;
        }

        // 创建结果数组
        jbyteArray result = env->NewByteArray(header.original_size);
        if (!result) {
            return nullptr;
        }
        JByteArrayGuard resultDataGuard(env, result);

        if (!resultDataGuard.isValid()) {
            env->DeleteLocalRef(result);
            return nullptr;
        }

        jbyte* resultData = resultDataGuard.get();

        // 复制加密数据
        memcpy(resultData, encryptedData, header.original_size);

        // 解密数据
        decryptFunc(resultData, header.original_size, key, keyLen);

        if (isValid) *isValid = true;
        return result;
    }

    // 验证是否为加密文件（不读取整个文件）
    static inline bool isEncryptedFile(const jbyte* fileData, jsize fileSize) {
        if (fileSize < HEADER_SIZE || !fileData) {
            return false;
        }

        EnhancedFileHeader header = readHeaderFromBytes(fileData);
        return validateHeader(header);
    }
}
#pragma clang diagnostic pop
#pragma clang diagnostic pop