// Point the DB at a closed port BEFORE requiring anything that builds the pool.
// The only code path here that reaches the database (the empty-honeypot case →
// username lookup) then fails fast with ECONNREFUSED instead of opening a real
// pooled connection that would keep this test process alive and hang the runner.
process.env.DB_HOST = '127.0.0.1'
process.env.DB_PORT = '59999'

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

const authCtrl = require('../src/router/v1/auth/auth.controller')
const botScore = require('../src/middleware/botScore')
const lp = require('../src/middleware/loginProtection')
const db = require('../src/utils/db')

// Release the DB pool so the process can exit cleanly even if a connection was
// created during module load.
after(() => db.close())

// Minimal res double capturing status/json; set() is a no-op for headers.
function mockRes() {
  return {
    statusCode: 200,
    body: null,
    status(c) {
      this.statusCode = c
      return this
    },
    json(b) {
      this.body = b
      return this
    },
    set() {
      return this
    },
  }
}

beforeEach(() => {
  botScore._reset()
  lp._reset()
})

test('honeypot field name matches what the client renders', () => {
  assert.equal(authCtrl.HONEYPOT_FIELD, 'company')
})

test('a filled honeypot fails generically and bans the IP', async () => {
  const ip = '203.0.113.70'
  const req = {
    ip,
    body: { username: 'admin', password: 'whatever', [authCtrl.HONEYPOT_FIELD]: 'Acme Corp' },
  }
  const res = mockRes()
  await authCtrl.login(req, res)

  // Generic failure — never says the honeypot was the reason.
  assert.equal(res.statusCode, 401)
  assert.match(res.body.message, /incorrect username or password/i)
  assert.doesNotMatch(res.body.message, /honeypot|bot|company/i)

  // Scored as an unambiguous bot: instant ban + backoff started.
  assert.equal(botScore.isBanned(ip), true)
  assert.ok(lp.retryAfterMs(ip) > 0)
})

test('an empty honeypot does NOT trigger bot scoring (branch not taken)', async () => {
  const ip = '203.0.113.71'
  const req = { ip, body: { username: 'admin', password: 'whatever', [authCtrl.HONEYPOT_FIELD]: '' } }
  const res = mockRes()
  // With an empty honeypot the code proceeds to the DB lookup, which has no
  // connection in this unit test and is caught → 500. The point of this test is
  // only that the honeypot branch did not fire, so the IP is not banned.
  await authCtrl.login(req, res)
  assert.equal(botScore.isBanned(ip), false)
})
