/* test/logger.test.js
 *
 * Validates the structured logger redacts secrets and emits JSON.
 */
'use strict';

const assert = require('assert');
const { logger } = require('../middleware/logger');

const TESTS = [];
const test = (n, fn) => TESTS.push({ name: n, fn });

test('logger.info emits JSON to stdout', () => {
  // Capture stdout
  const chunks = [];
  const real = process.stdout.write.bind(process.stdout);
  process.stdout.write = (s) => { chunks.push(s); return true; };
  logger.info('test.event', { foo: 'bar' });
  process.stdout.write = real;
  const line = chunks.join('').trim();
  assert.ok(line.length > 0, 'should have written a line');
  const obj = JSON.parse(line);
  assert.strictEqual(obj.event, 'test.event');
  assert.strictEqual(obj.foo, 'bar');
  assert.ok(obj.ts, 'should have a timestamp');
});

test('redacts password / token / key fields', () => {
  const chunks = [];
  const real = process.stdout.write.bind(process.stdout);
  process.stdout.write = (s) => { chunks.push(s); return true; };
  logger.info('test.redact', {
    password: 'supersecret',
    api_key: 're_ABCDEFGHIJK1234567890',
    Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.longjwt.payload',
    body: 'normal string',
  });
  process.stdout.write = real;
  const obj = JSON.parse(chunks.join('').trim());
  assert.notStrictEqual(obj.password, 'supersecret', 'password must be redacted');
  assert.notStrictEqual(obj.api_key, 're_ABCDEFGHIJK1234567890', 'api_key must be redacted');
  assert.notStrictEqual(obj.Authorization, 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.longjwt.payload', 'Authorization must be redacted');
  assert.strictEqual(obj.body, 'normal string', 'unrelated fields must NOT be redacted');
});

test('long opaque strings get a tail', () => {
  const long = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
  const chunks = [];
  const real = process.stdout.write.bind(process.stdout);
  process.stdout.write = (s) => { chunks.push(s); return true; };
  logger.info('test.tail', { jwt: long });
  process.stdout.write = real;
  const obj = JSON.parse(chunks.join('').trim());
  // 'jwt' is not in REDACT_KEYS, so it goes through the long-string branch
  assert.ok(obj.jwt.includes('…'), 'long opaque strings should be tail-truncated');
  assert.ok(obj.jwt.includes('len='), 'should include length');
});

module.exports = TESTS;
