import { afterEach, describe, expect, mock, spyOn } from "bun:test"
import { Effect, Layer } from "effect"
import * as Log from "@saeeol/core/util/log"
import { Instance } from "../../src/project/instance"
import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
import * as CrossSpawnSpawner from "@saeeol/core/cross-spawn-spawner"
import { testEffect } from "../lib/effect"

const err = new Error("indexing import failed")

mock.module("@/saeeol/indexing", () => {
  throw err
})

const { ToolRegistry } = await import("../../src/tool/registry")

const node = CrossSpawnSpawner.defaultLayer
const it = testEffect(Layer.mergeAll(ToolRegistry.defaultLayer, node))

afterEach(async () => {
  await disposeAllInstances()
})

describe("saeeol tool registry indexing import failure", () => {
  it.live("keeps non-indexing tools when the indexing module cannot load", () =>
    provideTmpdirInstance(
      () =>
        Effect.gen(function* () {
          const logger = Log.create({ service: "saeeol-tool-registry" })
          const warn = spyOn(logger, "warn").mockImplementation(() => {})

          try {
            const registry = yield* ToolRegistry.Service
            const ids = yield* registry.ids()

            expect(ids).not.toContain("semantic_search")
            expect(ids).toContain("question")
            expect(ids).toContain("read")
            expect(ids).toContain("suggest")
            expect(warn.mock.calls[0]?.[0]).toBe("semantic search unavailable")
            expect(warn.mock.calls[0]?.[1]?.err).toBeDefined()
          } finally {
            warn.mockRestore()
          }
        }),
      { git: true },
    ),
  )
})
