import Foundation

enum GeminiAPITestHelpers {
    static func dataLoader(
        handler: @escaping @Sendable (URLRequest) throws -> (HTTPURLResponse, Data))
        -> @Sendable (URLRequest) async throws -> (Data, URLResponse)
    {
        { request in
            let (response, data) = try handler(request)
            return (data, response)
        }
    }

    static func response(url: String, status: Int, body: Data) -> (HTTPURLResponse, Data) {
        let response = HTTPURLResponse(
            url: URL(string: url)!,
            statusCode: status,
            httpVersion: nil,
            headerFields: ["Content-Type": "application/json"])!
        return (response, body)
    }

    static func jsonData(_ payload: [String: Any]) -> Data {
        (try? JSONSerialization.data(withJSONObject: payload)) ?? Data()
    }

    static func sampleQuotaResponse() -> Data {
        self.jsonData([
            "buckets": [
                [
                    "modelId": "gemini-2.5-pro",
                    "remainingFraction": 0.6,
                    "resetTime": "2025-01-01T00:00:00Z",
                ],
                [
                    "modelId": "gemini-2.5-flash",
                    "remainingFraction": 0.9,
                    "resetTime": "2025-01-01T00:00:00Z",
                ],
                [
                    "modelId": "gemini-2.5-flash-lite",
                    "remainingFraction": 0.8,
                    "resetTime": "2025-01-01T00:00:00Z",
                ],
            ],
        ])
    }

    static func sampleFlashQuotaResponse() -> Data {
        self.jsonData([
            "buckets": [
                [
                    "modelId": "gemini-2.5-flash",
                    "remainingFraction": 0.9,
                    "resetTime": "2025-01-01T00:00:00Z",
                ],
                [
                    "modelId": "gemini-2.5-flash",
                    "remainingFraction": 0.4,
                    "resetTime": "2025-01-01T00:00:00Z",
                ],
            ],
        ])
    }

    static func makeIDToken(email: String, hostedDomain: String? = nil) -> String {
        var payload: [String: Any] = ["email": email]
        if let hd = hostedDomain {
            payload["hd"] = hd
        }
        let data = (try? JSONSerialization.data(withJSONObject: payload)) ?? Data()
        var encoded = data.base64EncodedString()
        encoded = encoded.replacingOccurrences(of: "+", with: "-")
        encoded = encoded.replacingOccurrences(of: "/", with: "_")
        encoded = encoded.replacingOccurrences(of: "=", with: "")
        return "header.\(encoded).sig"
    }

    static func loadCodeAssistResponse(
        tierId: String?,
        projectId: String? = nil,
        paidTierName: String? = nil) -> Data
    {
        var payload: [String: Any] = [:]
        if let tierId {
            payload["currentTier"] = [
                "id": tierId,
                "name": tierId.replacingOccurrences(of: "-tier", with: ""),
            ]
        }
        if let projectId {
            payload["cloudaicompanionProject"] = projectId
        }
        if let paidTierName {
            payload["paidTier"] = [
                "name": paidTierName,
            ]
        }
        return self.jsonData(payload)
    }

    static func loadCodeAssistConsumerPlusResponse(projectId: String? = "cloudaicompanion-123") -> Data {
        self.loadCodeAssistResponse(
            tierId: "free-tier",
            projectId: projectId,
            paidTierName: "Plus")
    }

    static func loadCodeAssistFreeTierResponse() -> Data {
        self.loadCodeAssistResponse(tierId: "free-tier")
    }

    static func loadCodeAssistStandardTierResponse() -> Data {
        self.loadCodeAssistResponse(tierId: "standard-tier")
    }

    static func loadCodeAssistGoogleOneProResponse(projectId: String? = "cloudaicompanion-123") -> Data {
        self.loadCodeAssistResponse(
            tierId: "standard-tier",
            projectId: projectId,
            paidTierName: "Gemini Code Assist in Google One AI Pro")
    }

    static func loadCodeAssistLegacyTierResponse() -> Data {
        self.loadCodeAssistResponse(tierId: "legacy-tier")
    }

    static func consumerTierDeprecationResponse() -> Data {
        self.jsonData([
            "error": [
                "code": 403,
                "message": """
                IneligibleTierError / UNSUPPORTED_CLIENT: This client is no longer supported for \
                Gemini Code Assist for individuals. To continue using Gemini, please migrate to the \
                Antigravity suite of products.
                """,
                "status": "PERMISSION_DENIED",
            ],
        ])
    }
}
