//
//  QiniuTokenSigner.swift
//  ylgamehall
//
//  七牛上传 token 客户端自签（HMAC-SHA1 + Base64URL）。
//  与 msext QiniuManager.m:200-230 generateUploadToken 等价算法。
//
//  putPolicy 结构：
//    { "scope": "iosaudio[:key]", "deadline": now + expiresIn }
//  签名流程：
//    putPolicy JSON → Base64URL → HMAC-SHA1(secretKey) → Base64URL
//    → `${AccessKey}:${sign}:${encodedPolicy}`
//
//  ⚠️ 用 CryptoKit（iOS 13+），不依赖 Qiniu SDK，纯 Swift 自签 token。
//

import Foundation
import CryptoKit

/// 七牛上传 token 自签。整体 nonisolated，actor 内可直接调（不需要 await MainActor.run）。
public enum QiniuTokenSigner {

    /// 生成上传 token。
    /// - Parameters:
    ///   - key: 上传文件 key（可空：scope = bucket，allow override；非空：scope = bucket:key）
    ///   - expiresIn: token 有效时长（默认 3600 秒）
    public nonisolated static func uploadToken(key: String? = nil, expiresIn: TimeInterval = 3600) -> String {
        // 1. 拼 scope
        let scope: String
        if let key, !key.isEmpty {
            scope = "\(QiniuConfig.bucketName):\(key)"
        } else {
            scope = QiniuConfig.bucketName
        }
        let deadline = Int(Date().timeIntervalSince1970 + expiresIn)

        // 2. putPolicy JSON（注意 key 顺序与 msext 等价：scope / deadline，
        //    实际七牛后端不要求顺序，但保持与 msext 一致便于排错）
        let putPolicy: [String: Any] = [
            "scope":    scope,
            "deadline": deadline
        ]
        let policyData = (try? JSONSerialization.data(withJSONObject: putPolicy, options: [.sortedKeys])) ?? Data()

        // 3. Base64URL(putPolicy)
        let encodedPolicy = base64URLEncode(policyData)

        // 4. HMAC-SHA1(secretKey, encodedPolicy) → Base64URL
        let secretKeyData = Data(QiniuConfig.secretKey.utf8)
        let key = SymmetricKey(data: secretKeyData)
        let signature = HMAC<Insecure.SHA1>.authenticationCode(
            for: Data(encodedPolicy.utf8),
            using: key
        )
        let encodedSign = base64URLEncode(Data(signature))

        // 5. token = AccessKey:encodedSign:encodedPolicy
        return "\(QiniuConfig.accessKey):\(encodedSign):\(encodedPolicy)"
    }

    /// Base64URL: 标准 Base64 把 + → -、/ → _、去掉末尾 =
    /// 与七牛 SDK `QNUrlSafeBase64.encodeData:` 等价
    private nonisolated static func base64URLEncode(_ data: Data) -> String {
        data.base64EncodedString()
            .replacingOccurrences(of: "+", with: "-")
            .replacingOccurrences(of: "/", with: "_")
            .replacingOccurrences(of: "=", with: "")
    }
}
