import express from 'express';
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import injectLogger from '../../src/middlewares/logger.js';

describe('logger middleware', () => {
  it('initializes', () => {
    const request = { header: (_key: string) => undefined } as express.Request;
    const response = { locals: {} } as express.Response;

    injectLogger(request, response, () => {});

    assert.deepEqual(response.locals.logger.getMetadata(), {
      correlation_id: undefined,
      request_id: undefined,
    });
  });

  it('correlation id', () => {
    const request = { header: (_key: string) => undefined } as express.Request;
    const response = { locals: { correlationId: '123', requestId: 'req-1' } } as express.Response;

    injectLogger(request, response, () => {});

    assert.deepEqual(response.locals.logger.getMetadata(), {
      correlation_id: '123',
      request_id: 'req-1',
    });
  });

  it('additional context', () => {
    const additional = JSON.stringify({
      foo: 'bar',
    });

    const request = { header: (_key: string) => additional } as express.Request;
    const response = { locals: { correlationId: '123' } } as express.Response;

    injectLogger(request, response, () => {});

    assert.deepEqual(response.locals.logger.getMetadata(), {
      correlation_id: '123',
      request_id: undefined,
      foo: 'bar',
    });
  });

  it('malformed additional context', () => {
    const request = { header: (_key: string) => 'nope' } as express.Request;
    const response = { locals: { correlationId: '123' } } as express.Response;

    injectLogger(request, response, () => {});

    assert.deepEqual(response.locals.logger.getMetadata(), {
      correlation_id: '123',
      request_id: undefined,
    });
  });

  it('sets logger level to debug when X-Unito-Debug header is present', testContext => {
    const request = {
      header: (key: string) => (key === 'X-Unito-Debug' ? 'true' : undefined),
    } as express.Request;
    const response = { locals: {} } as unknown as express.Response;

    const debugSpy = testContext.mock.method(global.console, 'debug', () => {});

    injectLogger(request, response, () => {});

    response.locals.logger.debug('should now be visible');
    assert.strictEqual(debugSpy.mock.calls.length, 1);
  });

  it('keeps default level when X-Unito-Debug header is absent', testContext => {
    const request = { header: (_key: string) => undefined } as express.Request;
    const response = { locals: {} } as unknown as express.Response;

    const debugSpy = testContext.mock.method(global.console, 'debug', () => {});

    injectLogger(request, response, () => {});

    response.locals.logger.debug('should be suppressed');
    assert.strictEqual(debugSpy.mock.calls.length, 0);
  });
});
