#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
激活码生成工具
用于根据客户设备UUID生成激活码

使用方法:
    python generate_activation_code.py <设备UUID> <客户密码>
    
示例:
    python generate_activation_code.py "12345678-1234-1234-1234-123456789ABC" "888888"

参数说明:
    设备UUID: 客户设备的主板UUID
    客户密码: 与程序中 customerPassword 一致的密码
"""

import sys
import base64
import hashlib

# ============ 配置参数 ============
ENCRYPT_KEY = b"GetonAgain2026SecretKey!@#$%"  # 加密密钥（必须与程序一致）
# ==================================

def encrypt(plain_text: str) -> str:
    """
    加密函数 - 与 C++ LicenseManager::encrypt 完全对应
    """
    data = plain_text.encode('utf-8')
    
    # 第一步：计算SHA256哈希
    hash_obj = hashlib.sha256(data)
    hash_bytes = hash_obj.digest()
    
    # 第二步：构造加密数据 = 哈希前8字节 + 原始数据
    to_encrypt = hash_bytes[:8] + data
    
    # 第三步：多层加密
    encrypted = bytearray()
    for i, byte in enumerate(to_encrypt):
        c = byte
        
        # 第一层：与主密钥XOR
        c = c ^ ENCRYPT_KEY[i % len(ENCRYPT_KEY)]
        
        # 第二层：字节置换（非线性变换）
        c = (c * 7 + 13) % 256
        
        # 第三层：与位置相关的混淆
        c = c ^ ((i * 31 + 17) % 256)
        
        encrypted.append(c)
    
    # 第四步：Base64编码
    return base64.b64encode(bytes(encrypted)).decode('latin-1')


def decrypt(encrypted_text: str) -> str:
    """
    解密函数 - 与 C++ LicenseManager::decrypt 完全对应
    """
    # Base64解码
    encrypted = bytearray(base64.b64decode(encrypted_text.encode('latin-1')))
    
    if len(encrypted) < 9:  # 至少8字节校验头 + 1字节数据
        return ""
    
    # 逆向解密
    decrypted = bytearray()
    for i, byte in enumerate(encrypted):
        c = byte
        
        # 逆向第三层：位置混淆
        c = c ^ ((i * 31 + 17) % 256)
        
        # 逆向第二层：字节置换的逆运算
        # 7 的模逆元是 183 (因为 7 * 183 = 1281 = 5 * 256 + 1)
        c = ((c + 256 - 13) * 183) % 256
        
        # 逆向第一层：与主密钥XOR
        c = c ^ ENCRYPT_KEY[i % len(ENCRYPT_KEY)]
        
        decrypted.append(c)
    
    # 提取校验头和原始数据
    stored_hash = bytes(decrypted[:8])
    original_data = bytes(decrypted[8:])
    
    # 验证哈希
    computed_hash = hashlib.sha256(original_data).digest()[:8]
    if computed_hash != stored_hash:
        print("警告: 哈希校验失败，数据可能已损坏")
        return ""
    
    return original_data.decode('utf-8')


def generate_activation_code(uuid: str, password: str) -> str:
    """
    生成激活码
    格式: encrypt(UUID:password)
    """
    plain_text = f"{uuid}:{password}"
    return encrypt(plain_text)


def verify_activation_code(activation_code: str, expected_uuid: str, expected_password: str) -> bool:
    """验证激活码是否有效"""
    try:
        decrypted = decrypt(activation_code)
        
        if not decrypted or ':' not in decrypted:
            return False
        
        # 使用 rsplit 从右侧分割，只分割一次
        parts = decrypted.rsplit(':', 1)
        uuid = parts[0]
        password = parts[1]
        
        return uuid == expected_uuid and password == expected_password
        
    except Exception as e:
        print(f"验证错误: {e}")
        return False


def save_to_csv(uuid: str, activation_code: str, customer_name: str = ""):
    """
    将激活记录保存到CSV文件
    """
    import csv
    import os
    from datetime import datetime
    
    csv_file = "activation_records.csv"
    file_exists = os.path.exists(csv_file)
    
    # 获取当前时间
    activation_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    try:
        with open(csv_file, 'a', newline='', encoding='utf-8-sig') as f:
            writer = csv.writer(f)
            
            # 如果文件不存在，先写入表头
            if not file_exists:
                writer.writerow(['序号', '设备UUID', '激活码', '激活时间', '客户名称', '备注'])
            
            # 统计当前记录数作为序号
            record_num = 1
            if file_exists:
                with open(csv_file, 'r', encoding='utf-8-sig') as rf:
                    record_num = sum(1 for _ in rf)  # 包含表头的行数就是新记录的序号
            
            # 写入新记录
            writer.writerow([record_num, uuid, activation_code, activation_time, customer_name, ''])
        
        print(f"激活记录已保存到: {csv_file}")
        
    except Exception as e:
        print(f"保存CSV记录失败: {e}")


def main():
    # 检查参数
    if len(sys.argv) < 3:
        print("用法: python generate_activation_code.py <设备UUID> <客户密码>")
        print("示例: python generate_activation_code.py \"12345678-1234-1234-1234-123456789ABC\" \"888888\"")
        return 1
    
    uuid = sys.argv[1].strip()
    password = sys.argv[2].strip()
    
    if not uuid:
        print("错误: UUID 不能为空!")
        return 1
    
    if not password:
        print("错误: 密码不能为空!")
        return 1
    
    # 生成激活码
    activation_code = generate_activation_code(uuid, password)
    
    # 验证
    if not verify_activation_code(activation_code, uuid, password):
        print("错误: 激活码验证失败!")
        return 1
    
    # 保存激活码文件
    filename = f"license_{uuid[:8]}.gal"
    try:
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(activation_code)
    except Exception as e:
        print(f"保存文件失败: {e}")
        return 1
    
    # 记录到CSV
    save_to_csv(uuid, activation_code)
    
    # 输出结果
    print(f"UUID: {uuid}")
    print(f"密码: {password}")
    print(f"激活码: {activation_code}")
    print(f"文件: {filename}")
    print("完成")
    
    return 0

if __name__ == "__main__":
    sys.exit(main())
