import assert from 'node:assert/strict'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const workerRoot = path.resolve(__dirname, '../..')

function execMigrationOnce(db, file) {
  try {
    db.exec(fs.readFileSync(path.join(workerRoot, file), 'utf8'))
  } catch (error) {
    if (!/duplicate column|already exists/i.test(error?.message || '')) throw error
  }
}

test('providers keep legacy Qoder out of model providers while runtimes expose local CLI choices', async (t) => {
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aipros-providers-agentrun-'))
  process.env.DB_PATH = path.join(tempRoot, 'test.db')
  process.env.OUTPUTS_DIR = path.join(tempRoot, 'outputs')

  t.after(() => {
    fs.rmSync(tempRoot, { recursive: true, force: true })
  })

  const { default: app } = await import('../index.js')
  const { rawDB } = await import('../db.js')
  execMigrationOnce(rawDB, 'migrations/0005_llm_providers.sql')
  execMigrationOnce(rawDB, 'migrations/0006_qoder_provider.sql')
  execMigrationOnce(rawDB, 'migrations/0010_runtime_engines.sql')
  execMigrationOnce(rawDB, 'migrations/0011_runtime_engine_api_key.sql')
  execMigrationOnce(rawDB, 'migrations/0014_local_runtime_agents.sql')
  execMigrationOnce(rawDB, 'migrations/0015_runtime_agent_skill_refs.sql')
  rawDB.prepare(`
    UPDATE llm_providers
    SET enabled = 1,
        is_active = 1,
        api_key = ?
    WHERE code = 'qoder'
  `).run('pt-legacy-qoder-token')

  const listRes = await app.request('/api/providers', {
    headers: { 'X-User-Email': '494161546@qq.com' },
  })
  assert.equal(listRes.status, 200)
  const body = await listRes.json()
  assert.ok(body.list.some(p => p.protocol === 'agentrun'))
  assert.equal(body.list.some(p => p.protocol === 'qoder' || p.code === 'qoder'), false)

  const runtimeRes = await app.request('/api/runtimes', {
    headers: { 'X-User-Email': '494161546@qq.com' },
  })
  assert.equal(runtimeRes.status, 200)
  const runtimeBody = await runtimeRes.json()
  assert.ok(runtimeBody.runtimes.some(p => p.code === 'local-codex' && p.protocol === 'local-cli'))
  assert.ok(runtimeBody.agents.some(a => a.appliesTo.includes('create')))
  assert.ok(Object.prototype.hasOwnProperty.call(runtimeBody.agents[0], 'skillId'))

  const activateRes = await app.request('/api/providers/qoder/active', {
    method: 'POST',
    headers: { 'X-User-Email': '494161546@qq.com' },
  })
  assert.equal(activateRes.status, 410)
  const activateBody = await activateRes.json()
  assert.match(activateBody.error, /AgentRun|已下线|不再支持/)
})

test('retired runtime migration removes legacy Qoder provider rows', async (t) => {
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aipros-retire-runtime-'))
  process.env.DB_PATH = path.join(tempRoot, 'test.db')
  process.env.OUTPUTS_DIR = path.join(tempRoot, 'outputs')

  t.after(() => {
    fs.rmSync(tempRoot, { recursive: true, force: true })
  })

  const { rawDB } = await import('../db.js')
  execMigrationOnce(rawDB, 'migrations/0005_llm_providers.sql')
  execMigrationOnce(rawDB, 'migrations/0006_qoder_provider.sql')
  assert.ok(rawDB.prepare("SELECT 1 FROM llm_providers WHERE code = 'qoder'").get())

  execMigrationOnce(rawDB, 'migrations/0013_retire_legacy_runtime.sql')

  const row = rawDB.prepare("SELECT 1 FROM llm_providers WHERE code = 'qoder' OR protocol = 'qoder'").get()
  assert.equal(row, undefined)
})
