// Integration: when fetchSaeeolModels returns a 401 error result, ModelCache
// surfaces the failure and caches empty models (allowing re-auth via /connect).
// The real 401-fallback unit test lives in packages/gateway/test/api/models.test.ts.

import { test, expect, mock } from "bun:test"
import path from "path"
import * as Log from "@saeeol/core/util/log"

Log.init({ print: false })

// Simulate a 401 typed error result from the gateway
mock.module("@saeeol/gateway", () => ({
  fetchSaeeolModels: async () => ({
    models: {},
    error: { kind: "unauthorized", status: 401 },
  }),
  SAEEOL_OPENROUTER_BASE: "https://api.saeeol.ai/api/openrouter",
}))

mock.module("saeeol-copilot-auth", () => ({ default: () => ({}) }))
mock.module("saeeol-anthropic-auth", () => ({ default: () => ({}) }))
mock.module("@gitlab/saeeol-gitlab-auth", () => ({ default: () => ({}) }))

import { tmpdir } from "../fixture/fixture"
import { Instance } from "../../src/project/instance"
import { ModelCache } from "../../src/provider/model-cache"

const CONFIG = JSON.stringify({ $schema: "https://app.saeeol.ai/config.json" })

async function withInstance<T>(fn: () => Promise<T>): Promise<T> {
  await using tmp = await tmpdir({
    init: async (dir) => {
      await Bun.write(path.join(dir, "saeeol.json"), CONFIG)
    },
  })
  return Instance.provide({ directory: tmp.path, fn })
}

test("401 from gateway sets provider as failed in ModelCache", async () => {
  ModelCache.clear("saeeol")
  await withInstance(() => ModelCache.fetch("saeeol"))
  expect(ModelCache.failedProviders()).toContain("saeeol")
  expect(ModelCache.getFailure("saeeol")).toMatchObject({ kind: "unauthorized", status: 401 })
})

test("401 from gateway caches empty models (not undefined)", async () => {
  ModelCache.clear("saeeol")
  await withInstance(() => ModelCache.fetch("saeeol"))
  const cached = ModelCache.get("saeeol")
  expect(cached).toBeDefined()
  expect(Object.keys(cached!)).toHaveLength(0)
})
