import { describe, test, expect } from 'vitest'
import { loadEnv, DEFAULT_PAIRING_TTL_SEC, DEFAULT_PAIRING_MAX_REDEEM_ATTEMPTS } from '../src/env.js'
import { bytesToBase64 } from '../src/util/bytes.js'

const validPubkey = bytesToBase64(new Uint8Array(32).fill(7))

const base = (): NodeJS.ProcessEnv => ({
  PG_URL: 'postgres://u:p@localhost:5432/cp',
  REDIS_URL: 'redis://localhost:6379',
  CAPABILITY_SIGN_PUBKEY_B64: validPubkey,
  CA_INTERMEDIATE_KMS_KEY_REF: 'kms://key/intermediate',
  CA_INTERMEDIATE_CERT_PATH: '/etc/cp/intermediate.pem',
  NODE_MTLS_TRUST_BUNDLE_PATH: '/etc/cp/node-ca.pem',
  BASE_DOMAIN: 'term.example.com',
})

describe('T1 loadEnv (INV9 fail-fast)', () => {
  test('empty env throws listing every missing required key', () => {
    let msg = ''
    try {
      loadEnv({})
    } catch (e) {
      msg = e instanceof Error ? e.message : ''
    }
    expect(msg).toContain('PG_URL')
    expect(msg).toContain('REDIS_URL')
    expect(msg).toContain('CAPABILITY_SIGN_PUBKEY_B64')
    expect(msg).toContain('CA_INTERMEDIATE_KMS_KEY_REF')
    expect(msg).toContain('BASE_DOMAIN')
  })

  test('bad pgUrl throws', () => {
    expect(() => loadEnv({ ...base(), PG_URL: 'not a url' })).toThrow(/PG_URL/)
  })

  test('valid map parses', () => {
    const env = loadEnv(base())
    expect(env.baseDomain).toBe('term.example.com')
    expect(env.capabilitySignPubkey.length).toBe(32)
  })

  test('pairing ttl / max-attempts default when unset', () => {
    const env = loadEnv(base())
    expect(env.pairingTtlSec).toBe(DEFAULT_PAIRING_TTL_SEC)
    expect(env.pairingMaxRedeemAttempts).toBe(DEFAULT_PAIRING_MAX_REDEEM_ATTEMPTS)
  })

  test('explicit pairing overrides parse', () => {
    const env = loadEnv({ ...base(), PAIRING_TTL_SEC: '900', PAIRING_MAX_REDEEM_ATTEMPTS: '3' })
    expect(env.pairingTtlSec).toBe(900)
    expect(env.pairingMaxRedeemAttempts).toBe(3)
  })

  test('never echoes secret VALUES on failure (INV9)', () => {
    const secret = bytesToBase64(new Uint8Array(32).fill(9))
    try {
      loadEnv({ ...base(), CAPABILITY_SIGN_PUBKEY_B64: secret, PG_URL: 'bad' })
    } catch (e) {
      const msg = e instanceof Error ? e.message : ''
      expect(msg).not.toContain(secret)
    }
  })

  test('capability pubkey wrong length rejected', () => {
    const short = bytesToBase64(new Uint8Array(16))
    expect(() => loadEnv({ ...base(), CAPABILITY_SIGN_PUBKEY_B64: short })).toThrow(/32 bytes/)
  })
})
