import { describe, expect, it, vi } from 'vitest'
import type { AgentConfig } from '../src/config/agentConfig.js'
import {
  buildFrpcToml,
  isFrpRetired,
  spawnFrpc,
  type ChildLike,
} from '../src/transport/frpScaffold.js'

const CFG: AgentConfig = {
  relayUrl: 'wss://relay/agent',
  enrollUrl: 'https://x/enroll',
  stateDir: '/tmp/x',
  localTargetUrl: 'ws://127.0.0.1:3000',
  subdomain: 'host-42',
  hostId: null,
}

describe('frpScaffold (T6, v0.8 only)', () => {
  it('generates a loopback-only tls frpc.toml', () => {
    const toml = buildFrpcToml(CFG)
    expect(toml).toContain('local_ip = "127.0.0.1"')
    expect(toml).toContain('local_port = 3000')
    expect(toml).toContain('subdomain = "host-42"')
    expect(toml).toContain('tls_enable = true')
    expect(toml).not.toMatch(/local_ip = "(?!127\.0\.0\.1)/)
  })

  it('refuses a non-loopback local target (anti-SSRF)', () => {
    expect(() => buildFrpcToml({ ...CFG, localTargetUrl: 'ws://10.0.0.5:3000' })).toThrow()
  })

  it('propagates child exit to onExit', async () => {
    let exitHandler: ((code: number | null) => void) | null = null
    const child: ChildLike = {
      on: (_ev, cb) => {
        exitHandler = cb
      },
      kill: vi.fn(),
    }
    const scaffold = spawnFrpc(CFG, '/usr/bin/frpc', () => child)
    const seen: number[] = []
    scaffold.onExit((c) => seen.push(c))
    await scaffold.start()
    exitHandler!(7)
    expect(seen).toEqual([7])
  })

  it('retirement guard: retired once ed25519', () => {
    expect(isFrpRetired('ed25519')).toBe(true)
    expect(isFrpRetired('token')).toBe(false)
  })
})
