import assert from 'node:assert/strict'
import { existsSync, mkdtempSync, mkdirSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import test from 'node:test'
import { syncRuntimeHomeToolingBridge } from '../apps/desktop/src/main/runtime-home-bridge.ts'

function readLinkedTarget(path: string) {
  return readlinkSync(path)
}

test('runtime home tooling bridge mirrors curated tool config but not agent compatibility dirs', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-bridge-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(realHome, { recursive: true })
  mkdirSync(runtimeHome, { recursive: true })

  writeFileSync(join(realHome, '.gitconfig'), '[user]\n  name = Test User\n')
  mkdirSync(join(realHome, '.ssh'), { recursive: true })
  writeFileSync(join(realHome, '.ssh', 'config'), 'Host *\n  AddKeysToAgent yes\n')
  mkdirSync(join(realHome, '.agents', 'skills', 'rogue-skill'), { recursive: true })
  writeFileSync(join(realHome, '.agents', 'skills', 'rogue-skill', 'SKILL.md'), '# Rogue\n')
  mkdirSync(join(realHome, '.config', 'opencode', 'skills', 'rogue-skill'), { recursive: true })
  writeFileSync(join(realHome, '.config', 'opencode', 'skills', 'rogue-skill', 'SKILL.md'), '# Native Rogue\n')
  mkdirSync(join(realHome, '.config', 'gh-copilot'), { recursive: true })
  writeFileSync(join(realHome, '.config', 'gh-copilot', 'hosts.json'), '{"token":"native-copilot-token"}\n')
  mkdirSync(join(realHome, '.opencode', 'skills', 'legacy-rogue'), { recursive: true })
  writeFileSync(join(realHome, '.opencode', 'skills', 'legacy-rogue', 'SKILL.md'), '# Legacy Rogue\n')

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome })

    assert.equal(readLinkedTarget(join(runtimeHome, '.gitconfig')), join(realHome, '.gitconfig'))
    assert.equal(readLinkedTarget(join(runtimeHome, '.ssh')), join(realHome, '.ssh'))
    assert.equal(existsSync(join(runtimeHome, '.agents')), false)
    assert.equal(existsSync(join(runtimeHome, '.config', 'opencode')), false)
    assert.equal(existsSync(join(runtimeHome, '.config', 'gh-copilot')), false)
    assert.equal(existsSync(join(runtimeHome, '.opencode')), false)
  } catch (error) {
    // fall through to explicit assertions below
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})

test('runtime home tooling bridge removes stale Copilot config links from older builds', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-copilot-cleanup-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(join(realHome, '.config', 'gh-copilot'), { recursive: true })
  mkdirSync(join(runtimeHome, '.config'), { recursive: true })

  const source = join(realHome, '.config', 'gh-copilot')
  const target = join(runtimeHome, '.config', 'gh-copilot')
  symlinkSync(source, target)

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome })
    assert.equal(existsSync(target), false)
  } catch (error) {
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})

test('runtime home tooling bridge removes stale bridged entries when the source disappears', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-cleanup-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(realHome, { recursive: true })
  mkdirSync(runtimeHome, { recursive: true })

  const source = join(realHome, '.gitconfig')
  const target = join(runtimeHome, '.gitconfig')
  writeFileSync(source, '[user]\n  email = test@example.com\n')
  mkdirSync(runtimeHome, { recursive: true })
  symlinkSync(source, target)
  rmSync(source, { force: true })

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome, entries: ['.gitconfig'] })
    assert.equal(existsSync(target), false)
  } catch (error) {
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})

test('runtime home tooling bridge removes configured links when disabled', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-disabled-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(realHome, { recursive: true })
  mkdirSync(runtimeHome, { recursive: true })

  const source = join(realHome, '.gitconfig')
  const target = join(runtimeHome, '.gitconfig')
  writeFileSync(source, '[user]\n  email = test@example.com\n')
  symlinkSync(source, target)

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome, entries: ['.gitconfig'], enabled: false })
    assert.equal(existsSync(target), false)
  } catch (error) {
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})

test('runtime home tooling bridge leaves runtime-owned files when disabled', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-disabled-owned-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(realHome, { recursive: true })
  mkdirSync(runtimeHome, { recursive: true })

  const source = join(realHome, '.gitconfig')
  const target = join(runtimeHome, '.gitconfig')
  writeFileSync(source, '[user]\n  email = host@example.com\n')
  writeFileSync(target, '[user]\n  email = runtime@example.com\n')

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome, entries: ['.gitconfig'], enabled: false })
    assert.equal(readFileSync(target, 'utf8'), '[user]\n  email = runtime@example.com\n')
  } catch (error) {
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})

test('runtime home tooling bridge does not replace runtime-owned files when enabled', () => {
  const root = mkdtempSync(join(tmpdir(), 'opencowork-runtime-home-owned-enabled-'))
  const realHome = join(root, 'real-home')
  const runtimeHome = join(root, 'runtime-home')
  mkdirSync(realHome, { recursive: true })
  mkdirSync(runtimeHome, { recursive: true })

  const source = join(realHome, '.gitconfig')
  const target = join(runtimeHome, '.gitconfig')
  writeFileSync(source, '[user]\n  email = host@example.com\n')
  writeFileSync(target, '[user]\n  email = runtime@example.com\n')

  try {
    syncRuntimeHomeToolingBridge({ runtimeHome, realHome, entries: ['.gitconfig'] })
    assert.equal(readFileSync(target, 'utf8'), '[user]\n  email = runtime@example.com\n')
  } catch (error) {
    assert.fail(error instanceof Error ? error.message : String(error))
  } finally {
    rmSync(root, { recursive: true, force: true })
  }
})
