/**
 * Guarded plugin auto-detection (8.0.9) — the "install it and it's on" contract.
 *
 * With `plugins` unset, brainy probes for the first-party accelerator
 * (@soulcraft/cor). The probe applies the same loud posture as the explicit
 * list to everything except "not installed":
 *   - not installed            → plain brainy, silently (the free path)
 *   - installed + healthy      → registered and activated
 *   - installed + broken       → init() THROWS (import failure, invalid shape,
 *                                or failed activation — an installed
 *                                accelerator never silently vanishes)
 *   - plugins: [] / false      → no probe at all (explicit opt-out)
 *   - explicit list            → unchanged: required, loud on any failure
 *
 * The import is isolated behind the private `importPluginPackage` seam so the
 * three outcomes are simulated without the package being present.
 */
import { describe, it, expect, afterEach } from 'vitest'
import { Brainy, NounType } from '../../src/index.js'

const proto = Brainy.prototype as any
const origImport = proto.importPluginPackage

afterEach(() => {
  proto.importPluginPackage = origImport
})

/** Simulate the probe outcome per package name. */
function stubImport(fn: (pkg: string) => Promise<any>): string[] {
  const probed: string[] = []
  proto.importPluginPackage = async function (pkg: string) {
    probed.push(pkg)
    return fn(pkg)
  }
  return probed
}

function notInstalledError(pkg: string): Error {
  // Node's exact shape for a missing package in a dynamic ESM import.
  const e = new Error(`Cannot find package '${pkg}' imported from /app/index.js`)
  ;(e as any).code = 'ERR_MODULE_NOT_FOUND'
  return e
}

/** A minimal valid plugin that registers one well-known provider. */
function validPlugin(name: string) {
  return {
    name,
    activate: async (context: any) => {
      context.registerProvider('distance', { euclidean: (a: number[], b: number[]) => 0 })
      return true
    }
  }
}

describe('Guarded plugin auto-detection (plugins: undefined)', () => {
  it('not installed → plain brainy, no plugins, init succeeds silently', async () => {
    const probed = stubImport(async (pkg) => {
      throw notInstalledError(pkg)
    })
    const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true })
    await brain.init()
    expect(probed).toContain('@soulcraft/cor') // the probe ran…
    expect(brain.pluginRegistry.hasActivePlugins()).toBe(false) // …and found nothing, quietly
    const id = await brain.add({ data: 'works without any plugin', type: NounType.Concept })
    expect(id).toBeTruthy()
    await brain.close()
  })

  it('installed + healthy → auto-registered and activated', async () => {
    stubImport(async () => ({ default: validPlugin('@soulcraft/cor') }))
    const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true })
    await brain.init()
    expect(brain.pluginRegistry.getActivePlugins()).toContain('@soulcraft/cor')
    expect(brain.pluginRegistry.hasProvider('distance')).toBe(true)
    await brain.close()
  })

  it('installed but import fails (broken install) → init() throws, never a silent JS fallback', async () => {
    stubImport(async () => {
      // A resolution failure INSIDE the package (names a sub-path, not the
      // package) — present but broken, must be loud.
      const e = new Error(
        "Cannot find module '/app/node_modules/@soulcraft/cor/dist/native.js' imported from " +
          '/app/node_modules/@soulcraft/cor/dist/index.js'
      )
      ;(e as any).code = 'ERR_MODULE_NOT_FOUND'
      throw e
    })
    const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true })
    await expect(brain.init()).rejects.toThrow(/installed but failed to load/)
  })

  it('installed but not a valid plugin (missing activate) → init() throws', async () => {
    stubImport(async () => ({ default: { name: '@soulcraft/cor' } })) // no activate()
    const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true })
    await expect(brain.init()).rejects.toThrow(/not a valid Brainy plugin/)
  })

  it('installed but activation fails → init() throws (activateAll posture applies)', async () => {
    stubImport(async () => ({
      default: {
        name: '@soulcraft/cor',
        activate: async () => {
          throw new Error('native binary missing for platform')
        }
      }
    }))
    const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, silent: true })
    await expect(brain.init()).rejects.toThrow(/failed to activate/)
  })

  it('plugins: [] and plugins: false → no probe at all (explicit opt-out)', async () => {
    const probed = stubImport(async () => ({ default: validPlugin('@soulcraft/cor') }))
    for (const plugins of [[], false] as const) {
      const brain: any = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, plugins: plugins as any, silent: true })
      await brain.init()
      expect(brain.pluginRegistry.hasActivePlugins()).toBe(false)
      await brain.close()
    }
    expect(probed).toEqual([]) // the seam was never touched
  })

  it('explicit list is unchanged: a listed-but-missing plugin throws with the config-pointing message', async () => {
    stubImport(async (pkg) => {
      throw notInstalledError(pkg)
    })
    const brain: any = new Brainy({
      requireSubtype: false,
      storage: { type: 'memory' },
      plugins: ['@soulcraft/cor'],
      silent: true
    })
    await expect(brain.init()).rejects.toThrow(/listed in config\.plugins but could not be loaded/)
  })
})
