import Foundation
import Testing
@testable import CodexBar
@testable import CodexBarCore

@Suite(.serialized)
@MainActor
struct CodexManagedRoutingTests {
    @Test
    func `provider registry injects managed home when active source is managed account`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-registry")
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: "/tmp/codex-managed-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        settings._test_activeManagedCodexAccount = managedAccount
        settings.codexActiveSource = .managedAccount(id: managedAccount.id)
        defer {
            settings._test_activeManagedCodexAccount = nil
        }

        let codexEnv = ProviderRegistry.makeEnvironment(
            base: ["PATH": "/usr/bin"],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)
        let claudeEnv = ProviderRegistry.makeEnvironment(
            base: ["PATH": "/usr/bin"],
            provider: .claude,
            settings: settings,
            tokenOverride: nil)

        #expect(codexEnv["CODEX_HOME"] == managedAccount.managedHomePath)
        #expect(claudeEnv["CODEX_HOME"] == nil)
    }

    @Test
    func `provider registry scopes codex environment with source override without persisting selection`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-source-override-env")
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: "/tmp/codex-managed-override-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-override-\(UUID().uuidString).json")
        let store = FileManagedCodexAccountStore(fileURL: storeURL)
        try store.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [managedAccount]))
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .liveSystem
        defer {
            settings._test_managedCodexAccountStoreURL = nil
            try? FileManager.default.removeItem(at: storeURL)
        }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": "/Users/example/.codex"],
            provider: .codex,
            settings: settings,
            tokenOverride: nil,
            codexActiveSourceOverride: .managedAccount(id: managedAccount.id))

        #expect(env["CODEX_HOME"] == managedAccount.managedHomePath)
        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `provider registry builds codex snapshot with source override without persisting selection`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-source-override-snapshot")
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: "/tmp/codex-managed-override-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-snapshot-override-\(UUID().uuidString).json")
        let store = FileManagedCodexAccountStore(fileURL: storeURL)
        try store.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [managedAccount]))
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .liveSystem
        defer {
            settings._test_managedCodexAccountStoreURL = nil
            try? FileManager.default.removeItem(at: storeURL)
        }

        let snapshot = ProviderRegistry.makeSettingsSnapshot(
            settings: settings,
            tokenOverride: nil,
            codexActiveSourceOverride: .managedAccount(id: UUID()))

        #expect(snapshot.codex?.managedAccountTargetUnavailable == true)
        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `provider registry preserves ambient live system home when active source is live system`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-live-system-routing")
        let managedHomePath = "/tmp/managed-remote-home"
        let liveHomePath = "/tmp/system-remote-home"
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: managedHomePath,
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let liveSystemAccount = ObservedSystemCodexAccount(
            email: "system@example.com",
            codexHomePath: liveHomePath,
            observedAt: Date())

        settings._test_activeManagedCodexAccount = managedAccount
        settings._test_liveSystemCodexAccount = liveSystemAccount
        settings.codexActiveSource = .liveSystem
        defer {
            settings._test_activeManagedCodexAccount = nil
            settings._test_liveSystemCodexAccount = nil
        }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": liveHomePath],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(env["CODEX_HOME"] == liveHomePath)
        #expect(env["CODEX_HOME"] != managedHomePath)
    }

    @Test
    func `provider registry keeps managed home when live account differs`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-active-vs-live")
        let managedHomePath = "/tmp/managed-remote-home"
        let liveHomePath = "/tmp/system-remote-home"
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: managedHomePath,
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let liveSystemAccount = ObservedSystemCodexAccount(
            email: "system@example.com",
            codexHomePath: liveHomePath,
            observedAt: Date())

        settings._test_activeManagedCodexAccount = managedAccount
        settings._test_liveSystemCodexAccount = liveSystemAccount
        settings.codexActiveSource = .managedAccount(id: managedAccount.id)
        defer {
            settings._test_activeManagedCodexAccount = nil
            settings._test_liveSystemCodexAccount = nil
        }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": liveHomePath],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(env["CODEX_HOME"] == managedHomePath)
        #expect(env["CODEX_HOME"] != liveHomePath)
    }

    @Test
    func `provider registry prefers live system routing when managed and live share email`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-same-email-prefers-live")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        let liveHomePath = "/tmp/system-remote-home"
        defer { try? FileManager.default.removeItem(at: managedHome) }

        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "person@example.com",
            managedHomePath: managedHome.path,
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let liveSystemAccount = ObservedSystemCodexAccount(
            email: "PERSON@example.com",
            codexHomePath: liveHomePath,
            observedAt: Date())

        settings._test_activeManagedCodexAccount = managedAccount
        settings._test_liveSystemCodexAccount = liveSystemAccount
        settings.codexActiveSource = .managedAccount(id: managedAccount.id)
        defer {
            settings._test_activeManagedCodexAccount = nil
            settings._test_liveSystemCodexAccount = nil
        }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": liveHomePath],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(settings.codexResolvedActiveSource == .liveSystem)
        #expect(env["CODEX_HOME"] == liveHomePath)
        #expect(env["CODEX_HOME"] != managedHome.path)
    }

    @Test
    func `provider registry keeps managed routing when same email rows differ by identity strength`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-same-email-split-by-identity")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        let liveHomePath = "/tmp/system-remote-home"
        defer { try? FileManager.default.removeItem(at: managedHome) }

        try self.writeCodexAuthFile(
            homeURL: managedHome,
            email: "person@example.com",
            plan: "pro",
            accountId: "account-managed")
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "person@example.com",
            managedHomePath: managedHome.path,
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let liveSystemAccount = ObservedSystemCodexAccount(
            email: "PERSON@example.com",
            codexHomePath: liveHomePath,
            observedAt: Date(),
            identity: .emailOnly(normalizedEmail: "person@example.com"))

        settings._test_activeManagedCodexAccount = managedAccount
        settings._test_liveSystemCodexAccount = liveSystemAccount
        settings.codexActiveSource = .managedAccount(id: managedAccount.id)
        defer {
            settings._test_activeManagedCodexAccount = nil
            settings._test_liveSystemCodexAccount = nil
        }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": liveHomePath],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(settings.codexResolvedActiveSource == .managedAccount(id: managedAccount.id))
        #expect(env["CODEX_HOME"] == managedHome.path)
        #expect(env["CODEX_HOME"] != liveHomePath)
    }

    @Test
    func `persisted managed source corrects to live system when selected row collapses with live account`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-same-email-persist-correction")
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "person@example.com",
            managedHomePath: "/tmp/managed-remote-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let liveSystemAccount = ObservedSystemCodexAccount(
            email: "PERSON@example.com",
            codexHomePath: "/tmp/system-remote-home",
            observedAt: Date())

        settings._test_activeManagedCodexAccount = managedAccount
        settings._test_liveSystemCodexAccount = liveSystemAccount
        settings.codexActiveSource = .managedAccount(id: managedAccount.id)
        defer {
            settings._test_activeManagedCodexAccount = nil
            settings._test_liveSystemCodexAccount = nil
        }

        let corrected = settings.persistResolvedCodexActiveSourceCorrectionIfNeeded()

        #expect(corrected)
        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `codex provider refresh persists live correction for stale managed source`() async {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-provider-refresh-persists-correction")
        let ambientHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: ambientHome) }

        try? self.writeCodexAuthFile(homeURL: ambientHome, email: "live@example.com", plan: "pro")
        settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
            email: "live@example.com",
            codexHomePath: ambientHome.path,
            observedAt: Date())
        settings.codexActiveSource = .managedAccount(id: UUID())
        defer { settings._test_liveSystemCodexAccount = nil }

        let store = UsageStore(
            fetcher: UsageFetcher(environment: ["CODEX_HOME": ambientHome.path]),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: settings,
            startupBehavior: .testing)

        #expect(settings.codexActiveSource != .liveSystem)

        await store.refreshProvider(.codex, allowDisabled: true)

        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `full refresh persists live correction for stale managed source`() async {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-full-refresh-persists-correction")
        let ambientHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: ambientHome) }

        try? self.writeCodexAuthFile(homeURL: ambientHome, email: "live@example.com", plan: "pro")
        settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
            email: "live@example.com",
            codexHomePath: ambientHome.path,
            observedAt: Date())
        settings.codexActiveSource = .managedAccount(id: UUID())
        defer { settings._test_liveSystemCodexAccount = nil }

        let store = UsageStore(
            fetcher: UsageFetcher(environment: ["CODEX_HOME": ambientHome.path]),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: settings,
            startupBehavior: .testing)

        #expect(settings.codexActiveSource != .liveSystem)

        await store.refresh()

        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `provider registry fails closed when managed account store is unreadable`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-unreadable-store")
        settings._test_unreadableManagedCodexAccountStore = true
        settings.codexActiveSource = .managedAccount(id: UUID())
        defer { settings._test_unreadableManagedCodexAccountStore = false }

        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": "/Users/example/.codex"],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(env["CODEX_HOME"] != nil)
        #expect(env["CODEX_HOME"] != "/Users/example/.codex")
        #expect(env["CODEX_HOME"]?.isEmpty == false)
    }

    @Test
    func `provider registry bootstraps live system source instead of inferring managed fallback`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-unreadable-legacy-source")
        settings._test_unreadableManagedCodexAccountStore = true
        defer { settings._test_unreadableManagedCodexAccountStore = false }

        let ambientHome = "/Users/example/.codex"
        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": ambientHome],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)
        let snapshot = settings.codexSettingsSnapshot(tokenOverride: nil)

        #expect(env["CODEX_HOME"] == ambientHome)
        #expect(settings.providerConfig(for: .codex)?.codexActiveSource == nil)
        #expect(snapshot.managedAccountStoreUnreadable == false)
        #expect(snapshot.managedAccountTargetUnavailable == false)
    }

    @Test
    func `provider registry fails closed when selected managed source is missing from readable store`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-missing-managed-source")
        let storedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "stored@example.com",
            managedHomePath: "/tmp/stored-managed-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-routing-\(UUID().uuidString).json")
        let store = FileManagedCodexAccountStore(fileURL: storeURL)
        try store.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [storedAccount]))
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .managedAccount(id: UUID())
        settings._test_codexReconciliationEnvironment = ["CODEX_HOME": "/Users/example/.codex"]
        defer {
            settings._test_codexReconciliationEnvironment = nil
            settings._test_managedCodexAccountStoreURL = nil
            try? FileManager.default.removeItem(at: storeURL)
        }

        let ambientHome = "/Users/example/.codex"
        let expectedFailClosedPath = ManagedCodexHomeFactory.defaultRootURL()
            .appendingPathComponent("managed-store-unreadable", isDirectory: true)
            .path
        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": ambientHome],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(env["CODEX_HOME"] == expectedFailClosedPath)
        #expect(env["CODEX_HOME"] != ambientHome)
        #expect(env["CODEX_HOME"] != storedAccount.managedHomePath)
    }

    @Test
    func `codex settings snapshot marks missing selected managed source as unavailable`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-missing-managed-snapshot")
        let storedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "stored@example.com",
            managedHomePath: "/tmp/stored-managed-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-snapshot-\(UUID().uuidString).json")
        let store = FileManagedCodexAccountStore(fileURL: storeURL)
        try store.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [storedAccount]))
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .managedAccount(id: UUID())
        defer {
            settings._test_managedCodexAccountStoreURL = nil
            try? FileManager.default.removeItem(at: storeURL)
        }

        let snapshot = settings.codexSettingsSnapshot(tokenOverride: nil)

        #expect(snapshot.managedAccountStoreUnreadable == false)
        #expect(snapshot.managedAccountTargetUnavailable == true)
    }

    @Test
    func `codex settings snapshot ignores unreadable added account store when live system is active`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-live-system-snapshot")
        settings._test_unreadableManagedCodexAccountStore = true
        settings.codexActiveSource = .liveSystem
        defer { settings._test_unreadableManagedCodexAccountStore = false }

        let snapshot = settings.codexSettingsSnapshot(tokenOverride: nil)

        #expect(snapshot.managedAccountStoreUnreadable == false)
        #expect(snapshot.managedAccountTargetUnavailable == false)
    }

    @Test
    func `codex settings snapshot keeps unreadable managed store fail closed when live account is present`() {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-unreadable-store-live-present")
        settings._test_unreadableManagedCodexAccountStore = true
        settings.codexActiveSource = .managedAccount(id: UUID())
        settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
            email: "live@example.com",
            codexHomePath: "/Users/example/.codex",
            observedAt: Date(),
            identity: .providerAccount(id: "acct-live"))
        defer {
            settings._test_unreadableManagedCodexAccountStore = false
            settings._test_liveSystemCodexAccount = nil
        }

        let snapshot = settings.codexSettingsSnapshot(tokenOverride: nil)

        #expect(snapshot.managedAccountStoreUnreadable == true)
        #expect(snapshot.managedAccountTargetUnavailable == false)
    }

    @Test
    func `codex settings snapshot keeps missing managed target fail closed when live account is present`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-missing-managed-live-present")
        let storedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "stored@example.com",
            managedHomePath: "/tmp/stored-managed-home",
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-live-present-\(UUID().uuidString).json")
        let store = FileManagedCodexAccountStore(fileURL: storeURL)
        try store.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [storedAccount]))
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .managedAccount(id: UUID())
        settings._test_liveSystemCodexAccount = ObservedSystemCodexAccount(
            email: "live@example.com",
            codexHomePath: "/Users/example/.codex",
            observedAt: Date(),
            identity: .providerAccount(id: "acct-live"))
        defer {
            settings._test_managedCodexAccountStoreURL = nil
            settings._test_liveSystemCodexAccount = nil
            try? FileManager.default.removeItem(at: storeURL)
        }

        let snapshot = settings.codexSettingsSnapshot(tokenOverride: nil)

        #expect(snapshot.managedAccountStoreUnreadable == false)
        #expect(snapshot.managedAccountTargetUnavailable == true)
    }

    @Test
    func `provider registry ignores debug managed home override without explicit managed source`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-debug-home-override")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        settings._test_activeManagedCodexRemoteHomePath = managedHome.path
        defer { settings._test_activeManagedCodexRemoteHomePath = nil }
        try self.writeCodexAuthFile(homeURL: managedHome, email: "managed@example.com", plan: "pro")

        let ambientHome = "/Users/example/.codex"
        let env = ProviderRegistry.makeEnvironment(
            base: ["CODEX_HOME": ambientHome],
            provider: .codex,
            settings: settings,
            tokenOverride: nil)

        #expect(env["CODEX_HOME"] == ambientHome)
        #expect(settings.providerConfig(for: .codex)?.codexActiveSource == nil)
    }

    @Test
    func `provider registry builds codex fetcher scoped to managed home`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-registry-fetcher")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        settings._test_activeManagedCodexRemoteHomePath = managedHome.path
        settings.codexActiveSource = .managedAccount(id: UUID())
        try self.writeCodexAuthFile(homeURL: managedHome, email: "managed@example.com", plan: "pro")
        defer {
            settings._test_activeManagedCodexRemoteHomePath = nil
        }

        let browserDetection = BrowserDetection(cacheTTL: 0)
        let specs = ProviderRegistry.shared.specs(
            settings: settings,
            metadata: ProviderDescriptorRegistry.metadata,
            codexFetcher: UsageFetcher(environment: [:]),
            claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection),
            browserDetection: browserDetection)
        let context = try #require(specs[.codex]?.makeFetchContext())

        let account = context.fetcher.loadAccountInfo()
        #expect(account.email == "managed@example.com")
        #expect(account.plan == "pro")
    }

    @Test
    func `usage store builds codex fetch context with source override without persisting selection`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-usage-source-override")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }
        let managedAccount = ManagedCodexAccount(
            id: UUID(),
            email: "managed@example.com",
            managedHomePath: managedHome.path,
            createdAt: 1,
            updatedAt: 1,
            lastAuthenticatedAt: 1)
        let storeURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("codex-managed-usage-override-\(UUID().uuidString).json")
        let managedStore = FileManagedCodexAccountStore(fileURL: storeURL)
        try managedStore.storeAccounts(ManagedCodexAccountSet(
            version: FileManagedCodexAccountStore.currentVersion,
            accounts: [managedAccount]))
        try self.writeCodexAuthFile(homeURL: managedHome, email: "override@example.com", plan: "pro")
        settings._test_managedCodexAccountStoreURL = storeURL
        settings.codexActiveSource = .liveSystem
        defer {
            settings._test_managedCodexAccountStoreURL = nil
            try? FileManager.default.removeItem(at: storeURL)
        }
        let store = UsageStore(
            fetcher: UsageFetcher(environment: [:]),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: settings,
            startupBehavior: .testing)

        let context = store.makeFetchContext(
            provider: .codex,
            override: nil,
            codexActiveSourceOverride: .managedAccount(id: managedAccount.id))

        let account = context.fetcher.loadAccountInfo()
        #expect(account.email == "override@example.com")
        #expect(account.plan == "pro")
        #expect(settings.codexActiveSource == .liveSystem)
    }

    @Test
    func `usage store builds codex token account fetcher scoped to managed home`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-usage-store")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        settings._test_activeManagedCodexRemoteHomePath = managedHome.path
        settings.codexActiveSource = .managedAccount(id: UUID())
        try self.writeCodexAuthFile(homeURL: managedHome, email: "token@example.com", plan: "team")
        defer {
            settings._test_activeManagedCodexRemoteHomePath = nil
        }

        let store = UsageStore(
            fetcher: UsageFetcher(environment: [:]),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: settings,
            startupBehavior: .testing)
        let context = store.makeFetchContext(provider: .codex, override: nil)

        let account = context.fetcher.loadAccountInfo()
        #expect(account.email == "token@example.com")
        #expect(account.plan == "team")
    }

    @Test
    func `usage store builds codex credits fetcher scoped to managed home`() throws {
        let settings = self.makeSettingsStore(suite: "CodexManagedRoutingTests-credits-fetcher")
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        settings._test_activeManagedCodexRemoteHomePath = managedHome.path
        settings.codexActiveSource = .managedAccount(id: UUID())
        try self.writeCodexAuthFile(homeURL: managedHome, email: "credits@example.com", plan: "enterprise")
        defer {
            settings._test_activeManagedCodexRemoteHomePath = nil
        }

        let store = UsageStore(
            fetcher: UsageFetcher(environment: [:]),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: settings,
            startupBehavior: .testing)
        let account = store.codexCreditsFetcher().loadAccountInfo()

        #expect(account.email == "credits@example.com")
        #expect(account.plan == "enterprise")
    }

    @Test
    func `default managed codex identity reader preserves provider account from scoped auth`() throws {
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }
        try self.writeCodexAuthFile(
            homeURL: managedHome,
            email: "managed@example.com",
            plan: "pro",
            accountId: "managed-account-id")

        let reader = DefaultManagedCodexIdentityReader()
        let account = try reader.loadAccountIdentity(homePath: managedHome.path)

        #expect(account.email == "managed@example.com")
        #expect(account.plan == "pro")
        #expect(account.identity == .providerAccount(id: "managed-account-id"))
    }

    @Test
    func `codex O auth strategy availability reads auth from context env`() async throws {
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        let credentials = CodexOAuthCredentials(
            accessToken: "access-token",
            refreshToken: "refresh-token",
            idToken: nil,
            accountId: nil,
            lastRefresh: Date())
        try CodexOAuthCredentialsStore.save(credentials, env: ["CODEX_HOME": managedHome.path])

        let strategy = CodexOAuthFetchStrategy()
        let available = await strategy.isAvailable(self.makeContext(env: ["CODEX_HOME": managedHome.path]))

        #expect(available)
    }

    @Test
    func `codex O auth credentials store loads and saves using explicit env`() throws {
        let managedHome = FileManager.default.temporaryDirectory.appendingPathComponent(
            UUID().uuidString,
            isDirectory: true)
        defer { try? FileManager.default.removeItem(at: managedHome) }

        let credentials = CodexOAuthCredentials(
            accessToken: "access-token",
            refreshToken: "refresh-token",
            idToken: "id-token",
            accountId: "account-id",
            lastRefresh: Date())
        let env = ["CODEX_HOME": managedHome.path]

        try CodexOAuthCredentialsStore.save(credentials, env: env)

        let authURL = CodexOAuthCredentialsStore._authFileURLForTesting(env: env)
        #expect(authURL.path == managedHome.appendingPathComponent("auth.json").path)

        let loaded = try CodexOAuthCredentialsStore.load(env: env)
        #expect(loaded.accessToken == credentials.accessToken)
        #expect(loaded.refreshToken == credentials.refreshToken)
        #expect(loaded.idToken == credentials.idToken)
        #expect(loaded.accountId == credentials.accountId)
    }

    @Test
    func `codex no data message uses explicit environment home`() {
        let env = ["CODEX_HOME": "/tmp/managed-codex-home"]

        let message = CodexProviderDescriptor._noDataMessageForTesting(env: env)

        #expect(message.contains("/tmp/managed-codex-home/sessions"))
        #expect(message.contains("/tmp/managed-codex-home/archived_sessions"))
    }

    private func makeContext(env: [String: String]) -> ProviderFetchContext {
        let browserDetection = BrowserDetection(cacheTTL: 0)
        return ProviderFetchContext(
            runtime: .app,
            sourceMode: .auto,
            includeCredits: false,
            webTimeout: 60,
            webDebugDumpHTML: false,
            verbose: false,
            env: env,
            settings: nil,
            fetcher: UsageFetcher(),
            claudeFetcher: ClaudeUsageFetcher(browserDetection: browserDetection),
            browserDetection: browserDetection)
    }

    private func makeSettingsStore(suite: String) -> SettingsStore {
        let defaults = UserDefaults(suiteName: suite)!
        defaults.removePersistentDomain(forName: suite)
        let configStore = testConfigStore(suiteName: suite)
        return SettingsStore(
            userDefaults: defaults,
            configStore: configStore,
            zaiTokenStore: InMemoryZaiTokenStore(),
            syntheticTokenStore: InMemorySyntheticTokenStore(),
            codexCookieStore: InMemoryCookieHeaderStore(),
            claudeCookieStore: InMemoryCookieHeaderStore(),
            cursorCookieStore: InMemoryCookieHeaderStore(),
            opencodeCookieStore: InMemoryCookieHeaderStore(),
            factoryCookieStore: InMemoryCookieHeaderStore(),
            minimaxCookieStore: InMemoryMiniMaxCookieStore(),
            minimaxAPITokenStore: InMemoryMiniMaxAPITokenStore(),
            kimiTokenStore: InMemoryKimiTokenStore(),
            augmentCookieStore: InMemoryCookieHeaderStore(),
            ampCookieStore: InMemoryCookieHeaderStore(),
            copilotTokenStore: InMemoryCopilotTokenStore(),
            tokenAccountStore: InMemoryTokenAccountStore())
    }

    private func writeCodexAuthFile(
        homeURL: URL,
        email: String,
        plan: String,
        accountId: String? = nil) throws
    {
        try FileManager.default.createDirectory(at: homeURL, withIntermediateDirectories: true)
        var tokens: [String: Any] = [
            "accessToken": "access-token",
            "refreshToken": "refresh-token",
            "idToken": Self.fakeJWT(email: email, plan: plan, accountId: accountId),
        ]
        if let accountId {
            tokens["accountId"] = accountId
        }
        let auth = ["tokens": tokens]
        let data = try JSONSerialization.data(withJSONObject: auth)
        try data.write(to: homeURL.appendingPathComponent("auth.json"))
    }

    private static func fakeJWT(email: String, plan: String, accountId: String? = nil) -> String {
        let header = (try? JSONSerialization.data(withJSONObject: ["alg": "none"])) ?? Data()
        var authClaims: [String: Any] = [
            "chatgpt_plan_type": plan,
        ]
        if let accountId {
            authClaims["chatgpt_account_id"] = accountId
        }
        let payload = (try? JSONSerialization.data(withJSONObject: [
            "email": email,
            "chatgpt_plan_type": plan,
            "https://api.openai.com/auth": authClaims,
        ])) ?? Data()

        func base64URL(_ data: Data) -> String {
            data.base64EncodedString()
                .replacingOccurrences(of: "=", with: "")
                .replacingOccurrences(of: "+", with: "-")
                .replacingOccurrences(of: "/", with: "_")
        }

        return "\(base64URL(header)).\(base64URL(payload))."
    }
}

private final class InMemoryZaiTokenStore: ZaiTokenStoring, @unchecked Sendable {
    func loadToken() throws -> String? {
        nil
    }

    func storeToken(_: String?) throws {}
}

private final class InMemorySyntheticTokenStore: SyntheticTokenStoring, @unchecked Sendable {
    func loadToken() throws -> String? {
        nil
    }

    func storeToken(_: String?) throws {}
}
