import Foundation
import Testing
@testable import CodexBarCore

private final class AntigravityAttemptRecorder: @unchecked Sendable {
    private let lock = NSLock()
    private var endpoints: [AntigravityStatusProbe.AntigravityConnectionEndpoint] = []

    func append(_ endpoint: AntigravityStatusProbe.AntigravityConnectionEndpoint) {
        self.lock.lock()
        self.endpoints.append(endpoint)
        self.lock.unlock()
    }

    func snapshot() -> [AntigravityStatusProbe.AntigravityConnectionEndpoint] {
        self.lock.lock()
        let snapshot = self.endpoints
        self.lock.unlock()
        return snapshot
    }
}

struct AntigravityStatusProbeTests {
    @Test
    func `process detection accepts antigravity 2 unsuffixed language server`() {
        let command = """
        /Applications/Antigravity.app/Contents/Resources/bin/language_server --standalone \
        --override_ide_name antigravity --override_ide_version 2.0.0 \
        --csrf_token token --app_data_dir antigravity
        """

        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(command))
    }

    @Test
    func `process detection accepts antigravity language server paths with spaces`() {
        let command = """
        /Applications/Google Antigravity.app/Contents/Resources/bin/language_server --standalone \
        --override_ide_name antigravity --csrf_token token --app_data_dir antigravity
        """

        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(command))
    }

    @Test
    func `process detection accepts hyphenated language server from app bundle`() throws {
        let command = """
        /Applications/Google Antigravity.app/Contents/Resources/bin/language-server --standalone \
        --csrf_token token --extension_server_port 64123
        """

        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(command))

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: "  321 \(command)")
        #expect(result.pid == 321)
        #expect(result.csrfToken == "token")
        #expect(result.extensionPort == 64123)
    }

    @Test
    func `process detection keeps ignoring non language server antigravity helpers`() {
        let helper = """
        /Applications/Antigravity.app/Contents/Frameworks/Antigravity Helper.app/Contents/MacOS/Antigravity Helper \
        --type=renderer --user-data-dir=/Users/test/Library/Application Support/Antigravity
        """

        #expect(!AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(helper))
    }

    @Test
    func `process detection still accepts legacy antigravity language server`() {
        let command = """
        /Applications/Antigravity.app/Contents/Resources/bin/language_server_macos \
        --csrf_token token --app_data_dir antigravity
        """

        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(command))
    }

    @Test
    func `process detection accepts platform suffixed antigravity language server`() throws {
        let output = """
          101 /Applications/Antigravity.app/Contents/Resources/bin/language_server_macos_arm \
          --csrf_token ide-token --app_data_dir antigravity --extension_server_port 54977
        """

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: output, scope: .appOnly)

        #expect(result.pid == 101)
        #expect(result.csrfToken == "ide-token")
        #expect(result.extensionPort == 54977)
    }

    @Test
    func `process detection accepts antigravity cli without csrf token`() {
        // The CLI launches its language server without a `--csrf_token` flag.
        let node = """
        node /Users/test/.gemini/antigravity-cli/build/mcp-server.cjs \
        --app_data_dir /Users/test/.gemini/antigravity
        """
        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(node))

        let agy = "/Users/test/.local/bin/agy -p hello"
        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(agy))

        let agyUnderscore = "/usr/local/bin/agy --app_data_dir /Users/test/.gemini/antigravity_cli"
        #expect(AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(agyUnderscore))
    }

    @Test
    func `process detection ignores unrelated binaries containing agy substring`() {
        // "agy" must be path-anchored so unrelated commands do not match.
        #expect(!AntigravityStatusProbe.isAntigravityLanguageServerCommandLine("/usr/bin/legacy --run"))
        #expect(!AntigravityStatusProbe.isAntigravityLanguageServerCommandLine("/opt/imagymagic/bin/tool"))
    }

    @Test
    func `process detection ignores cli names outside explicit cli path segments`() {
        #expect(
            !AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(
                "/usr/bin/node /tmp/not-antigravity-cli/build/server.js"))
        #expect(
            !AntigravityStatusProbe.isAntigravityLanguageServerCommandLine(
                "/usr/bin/helper --workspace antigravity-cli"))
    }

    @Test
    func `process kind distinguishes app ide language server and cli`() {
        let app = """
        /Applications/Antigravity.app/Contents/Resources/bin/language_server \
        --csrf_token token --app_data_dir antigravity
        """
        let ide = """
        /Applications/Antigravity IDE.app/Contents/Resources/app/extensions/antigravity/bin/language_server_macos_arm \
        --csrf_token token --app_data_dir antigravity-ide
        """
        #expect(AntigravityStatusProbe.antigravityProcessKind(app) == .app)
        #expect(AntigravityStatusProbe.antigravityProcessKind(ide) == .ide)
        #expect(AntigravityStatusProbe.antigravityProcessKind("/Users/test/.local/bin/agy -p hi") == .cli)
        #expect(
            AntigravityStatusProbe.antigravityProcessKind(
                "node /x/.gemini/antigravity-cli/build/mcp-server.cjs --app_data_dir /x/.gemini/antigravity") == .cli)
        #expect(AntigravityStatusProbe.antigravityProcessKind("/usr/bin/legacy --run") == nil)
    }

    @Test
    func `csrf token stays required for ide but optional for cli`() {
        // Desktop app/IDE with a token returns it.
        let appWithToken = """
        /Applications/Antigravity.app/Contents/Resources/bin/language_server \
        --csrf_token ide-token --app_data_dir antigravity
        """
        #expect(AntigravityStatusProbe.resolvedCSRFToken(forKind: .app, command: appWithToken) == "ide-token")

        // Tokenless desktop app is skipped (nil) so detection keeps scanning for a valid
        // server and preserves the missing-token diagnostic - no empty-token probe.
        let appNoToken = """
        /Applications/Antigravity.app/Contents/Resources/bin/language_server \
        --app_data_dir antigravity
        """
        #expect(AntigravityStatusProbe.resolvedCSRFToken(forKind: .app, command: appNoToken) == nil)

        // CLI without a token resolves to an empty token (its server needs none).
        #expect(
            AntigravityStatusProbe.resolvedCSRFToken(
                forKind: .cli, command: "/Users/test/.local/bin/agy -p hi")?.isEmpty == true)

        // A CLI that does carry a token still uses it.
        #expect(
            AntigravityStatusProbe.resolvedCSRFToken(
                forKind: .cli, command: "/Users/test/.local/bin/agy --csrf_token cli-token") == "cli-token")
    }

    @Test
    func `process scan skips tokenless ide before later valid ide`() throws {
        let tokenlessIDE =
            "  100 /Applications/Antigravity.app/Contents/Resources/bin/language_server --app_data_dir antigravity"
        let validIDE = "  101 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token ide-token --app_data_dir antigravity " +
            "--extension_server_port 64432 --extension_server_csrf_token extension-token"
        let output = [tokenlessIDE, validIDE].joined(separator: "\n")

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: output)

        #expect(result.pid == 101)
        #expect(result.csrfToken == "ide-token")
        #expect(result.extensionPort == 64432)
        #expect(result.extensionServerCSRFToken == "extension-token")
    }

    @Test
    func `process scan returns all valid app candidates`() throws {
        let firstApp = "  101 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token first-token --app_data_dir antigravity"
        let secondApp = "  102 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token second-token --app_data_dir antigravity " +
            "--extension_server_port 64432 --extension_server_csrf_token extension-token"
        let output = [firstApp, secondApp].joined(separator: "\n")

        let results = try AntigravityStatusProbe.processInfos(fromProcessListOutput: output, scope: .appOnly)

        #expect(results.map(\.pid) == [101, 102])
        #expect(results.map(\.csrfToken) == ["first-token", "second-token"])
        #expect(results.last?.extensionPort == 64432)
        #expect(results.last?.extensionServerCSRFToken == "extension-token")
    }

    @Test
    func `local snapshot score prefers quota summary over legacy model quotas`() {
        let legacy = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Low",
                    modelId: "gemini-3-pro-low",
                    remainingFraction: 0.9,
                    resetTime: Date(timeIntervalSince1970: 1_700_000_000),
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet",
                    modelId: "claude-sonnet",
                    remainingFraction: 0.5,
                    resetTime: Date(timeIntervalSince1970: 1_700_000_000),
                    resetDescription: nil),
            ],
            accountEmail: "user@example.com",
            accountPlan: "Pro",
            source: .local)
        let summary = AntigravityStatusSnapshot(
            quotaSummary: AntigravityQuotaSummary(
                description: nil,
                groups: [
                    AntigravityQuotaSummaryGroup(
                        displayName: "Gemini Models",
                        description: nil,
                        buckets: [
                            AntigravityQuotaSummaryBucket(
                                bucketId: "gemini-5h",
                                displayName: "Five Hour Limit",
                                remainingFraction: 0.9,
                                resetDescription: nil,
                                disabled: false),
                            AntigravityQuotaSummaryBucket(
                                bucketId: "gemini-weekly",
                                displayName: "Weekly Limit",
                                remainingFraction: 0.8,
                                resetDescription: nil,
                                disabled: false),
                        ]),
                    AntigravityQuotaSummaryGroup(
                        displayName: "Claude and GPT models",
                        description: nil,
                        buckets: [
                            AntigravityQuotaSummaryBucket(
                                bucketId: "3p-5h",
                                displayName: "Five Hour Limit",
                                remainingFraction: 0.7,
                                resetDescription: nil,
                                disabled: false),
                            AntigravityQuotaSummaryBucket(
                                bucketId: "3p-weekly",
                                displayName: "Weekly Limit",
                                remainingFraction: 0.6,
                                resetDescription: nil,
                                disabled: false),
                        ]),
                ]),
            accountEmail: "user@example.com",
            accountPlan: "Pro",
            source: .local)

        #expect(AntigravityStatusProbe.localSnapshotScore(summary) > AntigravityStatusProbe.localSnapshotScore(legacy))
    }

    @Test
    func `process scan reports missing csrf when only tokenless ide matches`() {
        let output = """
          100 /Applications/Antigravity.app/Contents/Resources/bin/language_server --app_data_dir antigravity
        """

        #expect(throws: AntigravityStatusProbeError.missingCSRFToken) {
            try AntigravityStatusProbe.processInfo(fromProcessListOutput: output)
        }
    }

    @Test
    func `process scan allows empty csrf only for explicit cli match`() throws {
        let output = """
          200 /Users/test/.local/bin/agy -p hello
        """

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: output)

        #expect(result.pid == 200)
        #expect(result.csrfToken.isEmpty)
        #expect(result.commandLine == "/Users/test/.local/bin/agy -p hello")
    }

    @Test
    func `ideOnly scope skips app and cli processes and reports not running`() {
        let output = "  200 /Users/test/.local/bin/agy -p hello"

        #expect(throws: AntigravityStatusProbeError.notRunning) {
            try AntigravityStatusProbe.processInfo(fromProcessListOutput: output, scope: .ideOnly)
        }

        let app = "  101 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token app-token --app_data_dir antigravity"
        #expect(throws: AntigravityStatusProbeError.notRunning) {
            try AntigravityStatusProbe.processInfo(fromProcessListOutput: app, scope: .ideOnly)
        }
    }

    @Test
    func `ideOnly scope still matches ide server listed after cli and app processes`() throws {
        let cli = "  200 /Users/test/.local/bin/agy -p hello"
        let app = "  101 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token app-token --app_data_dir antigravity"
        let ide = "  102 /Applications/Antigravity IDE.app/Contents/Resources/app/extensions/antigravity/bin/" +
            "language_server_macos_arm " +
            "--csrf_token ide-token --app_data_dir antigravity"
        let output = cli + "\n" + app + "\n" + ide

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: output, scope: .ideOnly)

        #expect(result.pid == 102)
        #expect(result.csrfToken == "ide-token")
    }

    @Test
    func `appOnly scope skips ide and cli processes`() throws {
        let cli = "  200 /Users/test/.local/bin/agy -p hello"
        let ide = "  102 /Applications/Antigravity IDE.app/Contents/Resources/app/extensions/antigravity/bin/" +
            "language_server_macos_arm --csrf_token ide-token --app_data_dir antigravity-ide"
        let app = "  101 /Applications/Antigravity.app/Contents/Resources/bin/language_server " +
            "--csrf_token app-token --app_data_dir antigravity"
        let output = cli + "\n" + ide + "\n" + app

        let result = try AntigravityStatusProbe.processInfo(fromProcessListOutput: output, scope: .appOnly)

        #expect(result.pid == 101)
        #expect(result.csrfToken == "app-token")
    }
}

extension AntigravityStatusProbeTests {
    @Test
    func `localhost trust policy only accepts local server trust challenges`() {
        #expect(
            LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "127.0.0.1",
                authenticationMethod: NSURLAuthenticationMethodServerTrust,
                hasServerTrust: true))
        #expect(
            LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "LOCALHOST",
                authenticationMethod: NSURLAuthenticationMethodServerTrust,
                hasServerTrust: true))

        #expect(
            !LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "cursor.com",
                authenticationMethod: NSURLAuthenticationMethodServerTrust,
                hasServerTrust: true))
        #expect(
            !LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "127.0.0.1",
                authenticationMethod: NSURLAuthenticationMethodHTTPBasic,
                hasServerTrust: true))
        #expect(
            !LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "127.0.0.1",
                authenticationMethod: NSURLAuthenticationMethodServerTrust,
                hasServerTrust: false))
    }

    @Test
    func `localhost trust policy rejects non loopback hostnames that contain localhost`() {
        #expect(
            !LocalhostTrustPolicy.shouldAcceptServerTrust(
                host: "localhost.example.com",
                authenticationMethod: NSURLAuthenticationMethodServerTrust,
                hasServerTrust: true))
    }

    @Test
    func `connection candidates preserve scheme order and endpoint tokens`() {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")

        #expect(
            candidates == [
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64440,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "extension-token",
                    source: .extensionServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `connection candidates restrict plain http probing to the declared extension port`() {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440, 64441],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: nil)

        #expect(
            candidates == [
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64440,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64441,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `connection candidates preserve extension fallback when extension token is unavailable`() {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: nil)

        #expect(
            candidates == [
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64440,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `connection candidates do not duplicate the same http target when ports overlap`() {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64432],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: nil)

        #expect(
            candidates == [
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `request endpoints retry extension server after language server success`() {
        let resolvedEndpoint = AntigravityStatusProbe.AntigravityConnectionEndpoint(
            scheme: "https",
            port: 64440,
            csrfToken: "language-token",
            source: .languageServer)

        let endpoints = AntigravityStatusProbe.requestEndpoints(
            resolvedEndpoint: resolvedEndpoint,
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")

        #expect(
            endpoints == [
                resolvedEndpoint,
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "extension-token",
                    source: .extensionServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `request endpoints preserve extension fallback when extension token is unavailable`() {
        let resolvedEndpoint = AntigravityStatusProbe.AntigravityConnectionEndpoint(
            scheme: "https",
            port: 64440,
            csrfToken: "language-token",
            source: .languageServer)

        let endpoints = AntigravityStatusProbe.requestEndpoints(
            resolvedEndpoint: resolvedEndpoint,
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: nil)

        #expect(
            endpoints == [
                resolvedEndpoint,
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
            ])
    }

    @Test
    func `request endpoints retry alternate token after extension server wins discovery`() {
        let resolvedEndpoint = AntigravityStatusProbe.AntigravityConnectionEndpoint(
            scheme: "http",
            port: 64432,
            csrfToken: "extension-token",
            source: .extensionServer)

        let endpoints = AntigravityStatusProbe.requestEndpoints(
            resolvedEndpoint: resolvedEndpoint,
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")

        #expect(
            endpoints == [
                resolvedEndpoint,
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "http",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .extensionServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64440,
                    csrfToken: "language-token",
                    source: .languageServer),
            ])
    }

    @Test
    func `request endpoints keep https language server fallback after extension probe wins`() {
        let resolvedEndpoint = AntigravityStatusProbe.AntigravityConnectionEndpoint(
            scheme: "http",
            port: 64432,
            csrfToken: "language-token",
            source: .extensionServer)

        let endpoints = AntigravityStatusProbe.requestEndpoints(
            resolvedEndpoint: resolvedEndpoint,
            listeningPorts: [64432, 64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: nil)

        #expect(
            endpoints == [
                resolvedEndpoint,
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64432,
                    csrfToken: "language-token",
                    source: .languageServer),
                AntigravityStatusProbe.AntigravityConnectionEndpoint(
                    scheme: "https",
                    port: 64440,
                    csrfToken: "language-token",
                    source: .languageServer),
            ])
    }

    @Test
    func `parsed request retries later endpoints after api level error payload`() async throws {
        let endpoints = [
            AntigravityStatusProbe.AntigravityConnectionEndpoint(
                scheme: "https",
                port: 64440,
                csrfToken: "bad-token",
                source: .languageServer),
            AntigravityStatusProbe.AntigravityConnectionEndpoint(
                scheme: "http",
                port: 64432,
                csrfToken: "good-token",
                source: .extensionServer),
        ]
        let attempted = AntigravityAttemptRecorder()

        let snapshot = try await AntigravityStatusProbe.makeParsedRequest(
            payload: AntigravityStatusProbe.RequestPayload(
                path: "/exa.language_server_pb.LanguageServerService/GetUserStatus",
                body: ["metadata": [:]]),
            context: AntigravityStatusProbe.RequestContext(
                endpoints: endpoints,
                timeout: 1),
            send: { _, endpoint, _ in
                attempted.append(endpoint)
                if endpoint.csrfToken == "bad-token" {
                    return Data(#"{"code":16}"#.utf8)
                }
                return Data(
                    #"""
                    {
                      "code": 0,
                      "userStatus": {
                        "email": "test@example.com",
                        "cascadeModelConfigData": {
                          "clientModelConfigs": []
                        }
                      }
                    }
                    """#.utf8)
            },
            parse: AntigravityStatusProbe.parseUserStatusResponse)

        #expect(snapshot.accountEmail == "test@example.com")
        #expect(attempted.snapshot() == endpoints)
    }

    @Test
    func `endpoint resolver prefers successful https language server candidate`() async throws {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")
        let attempted = AntigravityAttemptRecorder()

        let endpoint = try await AntigravityStatusProbe.resolveWorkingEndpoint(
            candidateEndpoints: candidates,
            timeout: 1)
        { endpoint, _ in
            attempted.append(endpoint)
            return endpoint.scheme == "https" && endpoint.port == 64440
        }

        #expect(endpoint == candidates[0])
        #expect(attempted.snapshot() == [candidates[0]])
    }

    @Test
    func `endpoint resolver falls back to extension server after https language server candidates`() async throws {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440, 64441],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")
        let attempted = AntigravityAttemptRecorder()

        let endpoint = try await AntigravityStatusProbe.resolveWorkingEndpoint(
            candidateEndpoints: candidates,
            timeout: 1)
        { endpoint, _ in
            attempted.append(endpoint)
            return endpoint.scheme == "http" && endpoint.port == 64432 && endpoint.source == .extensionServer
        }

        #expect(endpoint == candidates[2])
        #expect(attempted.snapshot() == Array(candidates.prefix(3)))
    }

    @Test
    func `endpoint resolver falls back to alternate extension token after primary token fails`() async throws {
        let candidates = AntigravityStatusProbe.connectionCandidates(
            listeningPorts: [64440],
            languageServerCSRFToken: "language-token",
            extensionServerPort: 64432,
            extensionServerCSRFToken: "extension-token")
        let attempted = AntigravityAttemptRecorder()

        let endpoint = try await AntigravityStatusProbe.resolveWorkingEndpoint(
            candidateEndpoints: candidates,
            timeout: 1)
        { endpoint, _ in
            attempted.append(endpoint)
            return endpoint.source == .extensionServer && endpoint.csrfToken == "language-token"
        }

        #expect(endpoint == candidates[2])
        #expect(attempted.snapshot() == candidates)
        #expect(endpoint.csrfToken == "language-token")
    }

    @Test
    func `parses user status response`() throws {
        let json = """
        {
          "code": 0,
          "userStatus": {
            "email": "test@example.com",
            "planStatus": {
              "planInfo": {
                "planName": "Pro"
              }
            },
            "cascadeModelConfigData": {
              "clientModelConfigs": [
                {
                  "label": "Claude 3.5 Sonnet",
                  "modelOrAlias": { "model": "claude-3-5-sonnet" },
                  "quotaInfo": { "remainingFraction": 0.5, "resetTime": "2025-12-24T10:00:00Z" }
                },
                {
                  "label": "Gemini Pro Low",
                  "modelOrAlias": { "model": "gemini-pro-low" },
                  "quotaInfo": { "remainingFraction": 0.8, "resetTime": "2025-12-24T11:00:00Z" }
                },
                {
                  "label": "Gemini Flash",
                  "modelOrAlias": { "model": "gemini-flash" },
                  "quotaInfo": { "remainingFraction": 0.2, "resetTime": "2025-12-24T12:00:00Z" }
                }
              ]
            }
          }
        }
        """

        let data = Data(json.utf8)
        let snapshot = try AntigravityStatusProbe.parseUserStatusResponse(data)
        #expect(snapshot.accountEmail == "test@example.com")
        #expect(snapshot.accountPlan == "Pro")
        #expect(snapshot.modelQuotas.count == 3)

        let usage = try snapshot.toUsageSnapshot()
        guard let primary = usage.primary else {
            return
        }
        #expect(primary.remainingPercent.rounded() == 20)
        #expect(usage.secondary?.remainingPercent.rounded() == 50)
        #expect(usage.tertiary == nil)
    }

    @Test
    func `prefers user tier name over generic plan info`() throws {
        let json = """
        {
          "code": 0,
          "userStatus": {
            "email": "ultra@example.com",
            "userTier": {
              "id": "google_ai_ultra",
              "name": "Google AI Ultra",
              "description": "Ultra tier"
            },
            "planStatus": {
              "planInfo": {
                "planName": "Pro"
              }
            },
            "cascadeModelConfigData": {
              "clientModelConfigs": []
            }
          }
        }
        """

        let data = Data(json.utf8)
        let snapshot = try AntigravityStatusProbe.parseUserStatusResponse(data)

        #expect(snapshot.accountEmail == "ultra@example.com")
        #expect(snapshot.accountPlan == "Google AI Ultra")
        #expect(snapshot.modelQuotas.isEmpty)
    }

    @Test
    func `falls back to plan info when user tier name is blank`() throws {
        let json = """
        {
          "code": 0,
          "userStatus": {
            "email": "fallback@example.com",
            "userTier": {
              "id": "google_ai_ultra",
              "name": "   ",
              "description": "Ultra tier"
            },
            "planStatus": {
              "planInfo": {
                "planName": "Pro"
              }
            },
            "cascadeModelConfigData": {
              "clientModelConfigs": []
            }
          }
        }
        """

        let data = Data(json.utf8)
        let snapshot = try AntigravityStatusProbe.parseUserStatusResponse(data)

        #expect(snapshot.accountEmail == "fallback@example.com")
        #expect(snapshot.accountPlan == "Pro")
        #expect(snapshot.modelQuotas.isEmpty)
    }

    @Test
    func `claude gpt pool can use thinking variants`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Claude Thinking",
                    modelId: "claude-thinking",
                    remainingFraction: 0.7,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet 4",
                    modelId: "claude-sonnet-4",
                    remainingFraction: 0.3,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary == nil)
        #expect(usage.secondary?.remainingPercent.rounded() == 30)
    }

    @Test
    func `claude gpt pool uses thinking model when it is the only claude option`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Claude Thinking",
                    modelId: "claude-thinking",
                    remainingFraction: 0.7,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Low",
                    modelId: "gemini-3-pro-low",
                    remainingFraction: 0.4,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 40)
        #expect(usage.secondary?.remainingPercent.rounded() == 70)
    }

    @Test
    func `gemini pool unavailable when only excluded variants exist`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini Pro Lite",
                    modelId: "gemini-3-pro-lite",
                    remainingFraction: 0.6,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet 4",
                    modelId: "claude-sonnet-4",
                    remainingFraction: 0.3,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary == nil)
        #expect(usage.secondary?.remainingPercent.rounded() == 30)
    }

    @Test
    func `gemini pool chooses most constrained pro variant`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro",
                    modelId: "gemini-3-pro",
                    remainingFraction: 0.9,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Low",
                    modelId: "gemini-3-pro-low",
                    remainingFraction: 0.4,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 40)
        #expect(usage.secondary == nil)
    }

    @Test
    func `gemini pool chooses standard pro when it is more constrained than low variant`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro",
                    modelId: "gemini-3-pro",
                    remainingFraction: 0.1,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Low",
                    modelId: "gemini-3-pro-low",
                    remainingFraction: 0.9,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 10)
        #expect(usage.secondary == nil)
    }

    @Test
    func `gemini pool ignores reset only placeholder when remaining data exists`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M36",
                    remainingFraction: nil,
                    resetTime: Date(timeIntervalSince1970: 1_735_000_000),
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "MODEL_PLACEHOLDER_M37",
                    remainingFraction: 1,
                    resetTime: Date(timeIntervalSince1970: 1_735_100_000),
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 100)
        #expect(usage.secondary == nil)
    }

    @Test
    func `gemini pool does not fallback to lite flash variant`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 2 Flash Lite",
                    modelId: "gemini-2-flash-lite",
                    remainingFraction: 0.2,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet 4",
                    modelId: "claude-sonnet-4",
                    remainingFraction: 0.3,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.tertiary == nil)
        #expect(usage.primary == nil)
        #expect(usage.secondary?.remainingPercent.rounded() == 30)
    }

    @Test
    func `falls back to labels when model ids are placeholders`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Claude Sonnet 4.6",
                    modelId: "MODEL_PLACEHOLDER_M35",
                    remainingFraction: 0.3,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M36",
                    remainingFraction: 0.4,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "MODEL_PLACEHOLDER_M47",
                    remainingFraction: 1,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 40)
        #expect(usage.secondary?.remainingPercent.rounded() == 30)
        #expect(usage.tertiary == nil)
    }

    @Test
    func `matches remote antigravity model names with parentheses`() throws {
        let resetTime = Date(timeIntervalSince1970: 1_775_000_000)
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Claude Opus 4.6 (Thinking)",
                    modelId: "MODEL_PLACEHOLDER_M50",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet 4.6 (Thinking)",
                    modelId: "MODEL_PLACEHOLDER_M51",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "MODEL_PLACEHOLDER_M52",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M53",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "MODEL_PLACEHOLDER_M54",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "GPT-OSS 120B (Medium)",
                    modelId: "MODEL_PLACEHOLDER_M55",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
            ],
            accountEmail: "user@example.com",
            accountPlan: "Pro")

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 100)
        #expect(usage.secondary?.remainingPercent.rounded() == 100)
        #expect(usage.tertiary == nil)
        #expect(usage.identity?.accountEmail == "user@example.com")
    }
}

extension AntigravityStatusProbeTests {
    @Test
    func `known model quota rows collapse into two usage pools`() throws {
        let resetTime = Date(timeIntervalSince1970: 1_775_000_000)
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "GPT-OSS 120B (Medium)",
                    modelId: "MODEL_PLACEHOLDER_M55",
                    remainingFraction: 0.25,
                    resetTime: resetTime,
                    resetDescription: "tomorrow"),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M53",
                    remainingFraction: 0.5,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Opus 4.6 (Thinking)",
                    modelId: "MODEL_PLACEHOLDER_M50",
                    remainingFraction: 0.75,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "MODEL_PLACEHOLDER_M52",
                    remainingFraction: 1,
                    resetTime: resetTime,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .local)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 50)
        #expect(usage.secondary?.remainingPercent.rounded() == 25)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `model without remaining fraction stays out of family summary and preserves reset metadata`() throws {
        let resetTime = Date(timeIntervalSince1970: 1_735_000_000)
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M36",
                    remainingFraction: nil,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "MODEL_PLACEHOLDER_M47",
                    remainingFraction: 1,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 100)
        #expect(usage.secondary == nil)
        #expect(usage.tertiary == nil)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `group without remaining fraction preserves reset metadata as unavailable grouped window`() throws {
        let resetTime = Date(timeIntervalSince1970: 1_735_000_000)
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M36",
                    remainingFraction: nil,
                    resetTime: resetTime,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary == nil)
        let modelWindow = try #require(usage.extraRateWindows?.first)
        #expect(modelWindow.id == "antigravity-gemini")
        #expect(modelWindow.title == "Gemini Models")
        #expect(modelWindow.window.resetsAt == resetTime)
        #expect(modelWindow.usageKnown == false)
    }

    @Test
    func `named rate windows default legacy payloads to known usage`() throws {
        let json = """
        {
          "id": "legacy-window",
          "title": "Legacy Window",
          "window": {
            "usedPercent": 42,
            "windowMinutes": null,
            "resetsAt": null,
            "resetDescription": null,
            "nextRegenPercent": null
          }
        }
        """

        let decoded = try JSONDecoder().decode(NamedRateWindow.self, from: Data(json.utf8))

        #expect(decoded.usageKnown)
    }

    @Test
    func `filtered variants stay out of summary but remain distinct extras`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Lite",
                    modelId: "gemini-3-pro-lite",
                    remainingFraction: 0.6,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash Lite",
                    modelId: "gemini-3-flash-lite",
                    remainingFraction: 0.2,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Tab Autocomplete",
                    modelId: "tab_autocomplete_model",
                    remainingFraction: 0.9,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: "test@example.com",
            accountPlan: "Pro",
            source: .local)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary == nil)
        #expect(usage.secondary == nil)
        #expect(usage.tertiary == nil)
        #expect(usage.extraRateWindows?.map(\.id) == [
            "gemini-3-pro-lite",
            "gemini-3-flash-lite",
            "tab_autocomplete_model",
        ])
        #expect(usage.accountEmail(for: .antigravity) == "test@example.com")
        #expect(usage.loginMethod(for: .antigravity) == "Pro")
    }

    // MARK: - Source-aware filter + sort tests

    @Test
    func `local source collapses opaque model ids into two usage pools`() throws {
        // Fixture A: 8 opaque-ID models, source .local -> two grouped quota pools
        let resetTime = Date(timeIntervalSince1970: 1_775_000_000)
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Claude Sonnet 4.6 (Thinking)",
                    modelId: "MODEL_PLACEHOLDER_M60",
                    remainingFraction: 0.8,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Opus 4.6 (Thinking)",
                    modelId: "MODEL_PLACEHOLDER_M61",
                    remainingFraction: 0.7,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (High)",
                    modelId: "MODEL_PLACEHOLDER_M62",
                    remainingFraction: 0.9,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M63",
                    remainingFraction: 0.4,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.5 Flash (High)",
                    modelId: "MODEL_PLACEHOLDER_M64",
                    remainingFraction: 0.6,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.5 Flash (Low)",
                    modelId: "MODEL_PLACEHOLDER_M65",
                    remainingFraction: 0.3,
                    resetTime: resetTime,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3.5 Flash (Medium)",
                    modelId: "MODEL_PLACEHOLDER_M66",
                    remainingFraction: 0.5,
                    resetTime: resetTime,
                    resetDescription: nil),
                // GPT-OSS pinned at remainingFraction == 1.0 - shown by local show-all
                AntigravityModelQuota(
                    label: "GPT-OSS 120B (Medium)",
                    modelId: "MODEL_PLACEHOLDER_M55",
                    remainingFraction: 1.0,
                    resetTime: resetTime,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .local)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 30)
        #expect(usage.secondary?.remainingPercent.rounded() == 70)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `remote source collapses recognized family models and hides unconsumed junk`() throws {
        // Fixture B: verified 13 remote models; recognized text models collapse into Gemini,
        // and unconsumed junk stays hidden.
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                // junk: image
                AntigravityModelQuota(
                    label: "Gemini 2.5 Flash Image",
                    modelId: "gemini-2-5-flash-image",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // junk: tab autocomplete
                AntigravityModelQuota(
                    label: "Tab Flash Lite Vertex",
                    modelId: "tab_flash_lite_vertex",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 2.5 Pro",
                    modelId: "gemini-2-5-pro",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "gemini-3-pro-high",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // junk: lite
                AntigravityModelQuota(
                    label: "Gemini 2.5 Flash Lite",
                    modelId: "gemini-2-5-flash-lite",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // junk: image
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Image",
                    modelId: "gemini-3-pro-image",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "gemini-3-flash",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // junk: lite
                AntigravityModelQuota(
                    label: "Gemini 3.1 Flash Lite",
                    modelId: "gemini-3-1-flash-lite",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (Low)",
                    modelId: "gemini-3-1-pro-low",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 3.1 Pro (High)",
                    modelId: "gemini-3-1-pro-high",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // junk: tab autocomplete
                AntigravityModelQuota(
                    label: "Tab Jump Flash Lite Vertex",
                    modelId: "tab_jump_flash_lite_vertex",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (Low)",
                    modelId: "gemini-3-pro-low",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                // survivor
                AntigravityModelQuota(
                    label: "Gemini 2.5 Flash",
                    modelId: "gemini-2-5-flash",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .remote)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 100)
        #expect(usage.secondary == nil)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `remote source shows consumed junk models despite filter`() throws {
        // Fixture C: junk models with remainingFraction < 0.999 must be shown
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                // consumed tab - should be shown
                AntigravityModelQuota(
                    label: "Tab Flash Lite Vertex",
                    modelId: "tab_flash_lite_vertex",
                    remainingFraction: 0.4,
                    resetTime: nil,
                    resetDescription: nil),
                // consumed image - should be shown
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Image",
                    modelId: "gemini-3-pro-image",
                    remainingFraction: 0.4,
                    resetTime: nil,
                    resetDescription: nil),
                // unconsumed sibling tab (0.9995 >= 0.999) - should be hidden
                AntigravityModelQuota(
                    label: "Tab Jump Flash Lite Vertex",
                    modelId: "tab_jump_flash_lite_vertex",
                    remainingFraction: 0.9995,
                    resetTime: nil,
                    resetDescription: nil),
                // a clean survivor for non-empty guard
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "gemini-3-flash",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .remote)

        let usage = try snapshot.toUsageSnapshot()
        let extraWindows = try #require(usage.extraRateWindows)
        let ids = extraWindows.map(\.id)

        // Consumed junk models shown despite being junk type
        #expect(ids.contains("tab_flash_lite_vertex"))
        #expect(ids.contains("gemini-3-pro-image"))

        // Unconsumed sibling stays hidden
        #expect(!ids.contains("tab_jump_flash_lite_vertex"))
    }

    @Test
    func `remote source image models do not drive family summary bars`() throws {
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Image",
                    modelId: "gemini-3-pro-image",
                    remainingFraction: 0.2,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "gemini-3-pro-high",
                    remainingFraction: 0.9,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash Image",
                    modelId: "gemini-3-flash-image",
                    remainingFraction: 0.1,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Flash",
                    modelId: "gemini-3-flash",
                    remainingFraction: 0.8,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .remote)

        let usage = try snapshot.toUsageSnapshot()

        #expect(usage.primary?.usedPercent == 20)
        #expect(usage.secondary == nil)
        #expect(usage.extraRateWindows?.map(\.id).contains("gemini-3-pro-image") == true)
        #expect(usage.extraRateWindows?.map(\.id).contains("gemini-3-flash-image") == true)
    }

    @Test
    func `remote source yields nil extra windows when all models are unconsumed junk`() throws {
        // Fixture D: all-junk-unconsumed -> extraRateWindows nil
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Tab Flash Lite Vertex",
                    modelId: "tab_flash_lite_vertex",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 2.5 Flash Lite",
                    modelId: "gemini-2-5-flash-lite",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro Image",
                    modelId: "gemini-3-pro-image",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Unknown Model X",
                    modelId: "unknown-model-x",
                    remainingFraction: 1.0,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .remote)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary == nil)
        #expect(usage.secondary == nil)
        #expect(usage.tertiary == nil)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `ordering edge cases collapse to most constrained usage pool`() throws {
        // Fixture F: local source; known Gemini Pro rows collapse into the Gemini pool
        // using the most constrained remaining fraction.
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (Low)",
                    modelId: "MODEL_PLACEHOLDER_M70",
                    remainingFraction: 0.5,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini 3 Pro (High)",
                    modelId: "MODEL_PLACEHOLDER_M71",
                    remainingFraction: 0.8,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Gemini Pro Experimental",
                    modelId: "MODEL_PLACEHOLDER_M72",
                    remainingFraction: 0.3,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Claude Sonnet 4",
                    modelId: "MODEL_PLACEHOLDER_M73",
                    remainingFraction: 0.9,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .local)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 30)
        #expect(usage.secondary?.remainingPercent.rounded() == 90)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `nil version unknown family models sort deterministically by label`() throws {
        // Strict-weak-ordering guard: two .unknown models with unparseable versions
        // should sort by label without trapping
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "Zebra Unknown Model",
                    modelId: "MODEL_PLACEHOLDER_MA",
                    remainingFraction: 0.5,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "Alpha Unknown Model",
                    modelId: "MODEL_PLACEHOLDER_MB",
                    remainingFraction: 0.5,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .local)

        let usage = try snapshot.toUsageSnapshot()
        let extraWindows = try #require(usage.extraRateWindows)
        let titles = extraWindows.map(\.title)

        // Deterministic: label tiebreaker -> Alpha before Zebra
        #expect(titles == ["Alpha Unknown Model", "Zebra Unknown Model"])
    }

    @Test
    func `hyphenated raw model ids without display name still map to gemini group`() throws {
        // When the remote catalog omits displayName/label, the raw hyphenated model id
        // becomes the label and still participates in the Gemini group.
        let snapshot = AntigravityStatusSnapshot(
            modelQuotas: [
                AntigravityModelQuota(
                    label: "gemini-3-pro-preview",
                    modelId: "gemini-3-pro-preview",
                    remainingFraction: 1,
                    resetTime: nil,
                    resetDescription: nil),
                AntigravityModelQuota(
                    label: "gemini-2.5-pro",
                    modelId: "gemini-2.5-pro",
                    remainingFraction: 1,
                    resetTime: nil,
                    resetDescription: nil),
            ],
            accountEmail: nil,
            accountPlan: nil,
            source: .remote)

        let usage = try snapshot.toUsageSnapshot()
        #expect(usage.primary?.remainingPercent.rounded() == 100)
        #expect(usage.extraRateWindows == nil)
    }

    @Test
    func `http probe errors still count as reachable`() {
        #expect(
            AntigravityStatusProbe.isReachableProbeError(
                AntigravityStatusProbeError.apiError("HTTP 403: Forbidden")))
        #expect(
            AntigravityStatusProbe.isReachableProbeError(
                AntigravityStatusProbeError.apiError("HTTP 404: Not Found")))
        #expect(
            !AntigravityStatusProbe.isReachableProbeError(
                AntigravityStatusProbeError.apiError("Invalid response")))
        #expect(!AntigravityStatusProbe.isReachableProbeError(AntigravityStatusProbeError.notRunning))
    }

    @Test
    func `fallback probe port prefers non extension candidate`() {
        #expect(
            AntigravityStatusProbe.fallbackProbePort(
                ports: [51170, 61775],
                extensionPort: 61775) == 51170)
        #expect(
            AntigravityStatusProbe.fallbackProbePort(
                ports: [61775],
                extensionPort: 61775) == 61775)
        #expect(
            AntigravityStatusProbe.fallbackProbePort(
                ports: [51170, 61775],
                extensionPort: nil) == 51170)
    }
}
