#!/usr/bin/env python3
"""
加密密钥轮换脚本

使用方法:
1. 生成新密钥:
   python scripts/rotate_encryption_key.py generate

2. 重新加密现有数据 (如果有):
   python scripts/rotate_encryption_key.py rotate --old-key=<旧密钥> --new-key=<新密钥>

安全注意事项:
- 在轮换前备份数据库
- 在维护窗口期间执行轮换
- 更新 .env 文件中的 ENCRYPTION_KEY
- 重启服务使新密钥生效
"""

import sys
import os
import argparse
from cryptography.fernet import Fernet

# 添加项目根目录到 Python 路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def generate_key():
    """生成新的加密密钥"""
    key = Fernet.generate_key().decode()
    print("\n" + "=" * 60)
    print("新的加密密钥已生成:")
    print("=" * 60)
    print(f"\n{key}\n")
    print("=" * 60)
    print("\n请将此密钥添加到 .env 文件中:")
    print(f'ENCRYPTION_KEY="{key}"')
    print("\n安全提示:")
    print("1. 请勿将此密钥提交到版本控制系统")
    print("2. 使用环境变量或密钥管理服务存储")
    print("3. 定期轮换密钥（建议每90天）")
    print("=" * 60 + "\n")
    return key


def rotate_keys(old_key: str, new_key: str):
    """
    使用新密钥重新加密数据

    注意: 当前系统中的加密数据主要是发货地址信息
    如果没有使用加密功能，可以跳过此步骤
    """
    try:
        old_cipher = Fernet(old_key.encode())
        new_cipher = Fernet(new_key.encode())
        print("密钥验证成功")

        # 这里可以添加数据库重新加密逻辑
        # 当前系统中加密使用较少，主要用于地址信息
        print("\n当前系统中加密数据较少，主要更新步骤:")
        print("1. 更新 .env 文件中的 ENCRYPTION_KEY")
        print("2. 重启后端服务")
        print("3. 新数据将使用新密钥加密")
        print("\n如有旧的加密数据需要重新加密，请联系开发人员")

    except Exception as e:
        print(f"错误: {e}")
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(description='加密密钥管理工具')
    subparsers = parser.add_subparsers(dest='command', help='可用命令')

    # 生成密钥命令
    subparsers.add_parser('generate', help='生成新的加密密钥')

    # 轮换密钥命令
    rotate_parser = subparsers.add_parser('rotate', help='轮换加密密钥')
    rotate_parser.add_argument('--old-key', required=True, help='旧的加密密钥')
    rotate_parser.add_argument('--new-key', required=True, help='新的加密密钥')

    args = parser.parse_args()

    if args.command == 'generate':
        generate_key()
    elif args.command == 'rotate':
        rotate_keys(args.old_key, args.new_key)
    else:
        parser.print_help()


if __name__ == '__main__':
    main()
