const { test } = require('node:test')
const assert = require('node:assert/strict')

const { parseTrustProxy, applyTrustProxy } = require('../src/utils/trustProxy')
const { startApp } = require('./_helper')

test('parseTrustProxy: default (unset/empty) is a single hop', () => {
  assert.equal(parseTrustProxy(''), 1)
  assert.equal(parseTrustProxy(undefined), 1)
})

test('parseTrustProxy: integer hop count', () => {
  assert.equal(parseTrustProxy('2'), 2)
  assert.equal(parseTrustProxy('0'), 0)
})

test('parseTrustProxy: "false" disables proxy trust', () => {
  assert.equal(parseTrustProxy('false'), false)
})

test('parseTrustProxy: blanket "true" is rejected and coerced to 1 (anti-spoof)', () => {
  assert.equal(parseTrustProxy('true'), 1)
})

test('parseTrustProxy: CSV of IPs/CIDRs becomes an array; single stays a string', () => {
  assert.deepEqual(parseTrustProxy('10.0.0.0/8, 172.18.0.1'), ['10.0.0.0/8', '172.18.0.1'])
  assert.equal(parseTrustProxy('172.18.0.1'), '172.18.0.1')
})

test('applyTrustProxy: with 1 hop, req.ip reflects X-Forwarded-For client', async () => {
  const app = await startApp((a) => {
    applyTrustProxy(a, '1')
    a.get('/ip', (req, res) => res.json({ ip: req.ip }))
  })
  try {
    const res = await fetch(`${app.url}/ip`, { headers: { 'X-Forwarded-For': '203.0.113.7' } })
    const body = await res.json()
    assert.equal(body.ip, '203.0.113.7')
  } finally {
    await app.close()
  }
})

test('applyTrustProxy: pinned to the peer IP, XFF from that peer is trusted', async () => {
  // Mirrors the production setup: TRUST_PROXY = ptero's LAN IP. Here the test
  // client's peer address is loopback, so pin to loopback and confirm XFF wins.
  const app = await startApp((a) => {
    applyTrustProxy(a, '127.0.0.1')
    a.get('/ip', (req, res) => res.json({ ip: req.ip }))
  })
  try {
    const res = await fetch(`${app.url}/ip`, { headers: { 'X-Forwarded-For': '203.0.113.9' } })
    const body = await res.json()
    assert.equal(body.ip, '203.0.113.9')
  } finally {
    await app.close()
  }
})

test('applyTrustProxy: pinned to a DIFFERENT IP, XFF from this peer is NOT trusted', async () => {
  // If ptero's IP is pinned but the connection comes from some other host, its
  // X-Forwarded-For is ignored — nothing else on the LAN can spoof a client IP.
  const app = await startApp((a) => {
    applyTrustProxy(a, '10.11.12.13') // not the loopback peer this test connects from
    a.get('/ip', (req, res) => res.json({ ip: req.ip }))
  })
  try {
    const res = await fetch(`${app.url}/ip`, { headers: { 'X-Forwarded-For': '203.0.113.9' } })
    const body = await res.json()
    assert.notEqual(body.ip, '203.0.113.9')
  } finally {
    await app.close()
  }
})

test('applyTrustProxy: with false, a forged X-Forwarded-For is ignored', async () => {
  const app = await startApp((a) => {
    applyTrustProxy(a, 'false')
    a.get('/ip', (req, res) => res.json({ ip: req.ip }))
  })
  try {
    const res = await fetch(`${app.url}/ip`, { headers: { 'X-Forwarded-For': '203.0.113.7' } })
    const body = await res.json()
    // The spoofed client IP must NOT be trusted — req.ip stays the loopback peer.
    assert.notEqual(body.ip, '203.0.113.7')
  } finally {
    await app.close()
  }
})
