import { describe, test, expect } from 'vitest'
import { loadDataPlaneConfig } from '../data-plane/config.js'

const base = {
  BASE_DOMAIN: 'term.example.com',
  TLS_CERT_PATH: '/etc/relay/cert.pem',
  TLS_KEY_PATH: '/etc/relay/key.pem',
  AGENT_CA_CERT_PATH: '/etc/relay/ca.pem',
  RELAY_NODE_ID: 'node-1',
} satisfies NodeJS.ProcessEnv

describe('loadDataPlaneConfig (T1, INV9 fail-fast)', () => {
  test('happy path returns a frozen typed config with defaults applied', () => {
    const cfg = loadDataPlaneConfig(base)
    expect(cfg.baseDomain).toBe('term.example.com')
    expect(cfg.bindHost).toBe('0.0.0.0')
    expect(cfg.maxFrameBytes).toBe(1024 * 1024)
    expect(cfg.initialWindowBytes).toBe(256 * 1024)
    expect(cfg.heartbeatIntervalMs).toBe(15_000)
    expect(cfg.routeTtlMs).toBe(45_000)
    // agentCaChainPath falls back to agentCaCertPath when unset.
    expect(cfg.agentCaChainPath).toBe('/etc/relay/ca.pem')
    expect(Object.isFrozen(cfg)).toBe(true)
  })

  test('throws when BASE_DOMAIN is missing', () => {
    expect(() => loadDataPlaneConfig({ ...base, BASE_DOMAIN: undefined })).toThrow(/baseDomain/)
  })

  test('throws when TLS_CERT_PATH / TLS_KEY_PATH missing (fail-fast)', () => {
    expect(() => loadDataPlaneConfig({ ...base, TLS_CERT_PATH: undefined })).toThrow(/tlsCertPath/)
    expect(() => loadDataPlaneConfig({ ...base, TLS_KEY_PATH: undefined })).toThrow(/tlsKeyPath/)
  })

  test('throws when AGENT_CA_CERT_PATH (mTLS trust-anchor) missing — Finding-4 footgun', () => {
    expect(() => loadDataPlaneConfig({ ...base, AGENT_CA_CERT_PATH: undefined })).toThrow(
      /agentCaCertPath/,
    )
  })

  test('throws on non-numeric MAX_FRAME_BYTES', () => {
    expect(() => loadDataPlaneConfig({ ...base, MAX_FRAME_BYTES: 'not-a-number' })).toThrow(
      /maxFrameBytes/,
    )
  })

  test('error message never echoes secret values (INV9)', () => {
    try {
      loadDataPlaneConfig({ ...base, TLS_KEY_PATH: undefined, MAX_FRAME_BYTES: 'xyz' })
      throw new Error('should have thrown')
    } catch (e) {
      const msg = (e as Error).message
      expect(msg).not.toContain('/etc/relay/key.pem')
      expect(msg).not.toContain('xyz')
    }
  })
})
