import express from 'express';
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import onFinish from '../../src/middlewares/finish.js';
import { RequestMetrics } from '../../src/resources/requestMetrics.js';

describe('finish middleware', () => {
  it('logs info', () => {
    let expected = '';
    let urlCategory: unknown;
    let eventHandler: () => void = () => {};

    const request = {
      method: 'GET',
      originalUrl: '/projects/123/tasks?limit=100',
      baseUrl: '',
      route: { path: '/projects/:id/tasks' },
    } as unknown as express.Request;
    const response = {
      on: (_event: string, func: () => void) => {
        eventHandler = func;
      },
      locals: {
        requestMetrics: RequestMetrics.startRequest(),
        logger: {
          info: (_message: string, metadata: { http?: { url_category?: string } }) => {
            expected = 'works!';
            urlCategory = metadata.http?.url_category;
          },
        },
      },
      statusCode: 200,
    } as unknown as express.Response;

    onFinish(request, response, () => {});
    eventHandler();

    assert.equal(expected, 'works!');
    assert.equal(urlCategory, '/projects/:id/tasks');
  });

  it('logs error', () => {
    let expected = '';
    let urlCategory: unknown;
    let eventHandler: () => void = () => {};

    const request = { method: 'GET', originalUrl: '/', baseUrl: '' } as express.Request;
    const response = {
      on: (_event: string, func: () => void) => {
        eventHandler = func;
      },
      locals: {
        requestMetrics: RequestMetrics.startRequest(),
        logger: {
          error: (_message: string, metadata: { http?: { url_category?: string } }) => {
            expected = 'works!';
            urlCategory = metadata.http?.url_category;
          },
        },
      },
      statusCode: 500,
    } as unknown as express.Response;

    onFinish(request, response, () => {});
    eventHandler();

    assert.equal(expected, 'works!');
    assert.equal(urlCategory, 'unmatched');
  });

  it('health success', () => {
    let expected = '';
    let eventHandler: () => void = () => {};

    const request = { originalUrl: '/health' } as express.Request;
    const response = {
      on: (_event: string, func: () => void) => {
        eventHandler = func;
      },
      locals: {
        requestMetrics: RequestMetrics.startRequest(),
        logger: {
          info: (_message: string) => {
            expected = 'ohoh!';
          },
        },
      },
      statusCode: 200,
    } as unknown as express.Response;

    onFinish(request, response, () => {});
    eventHandler();

    assert.equal(expected, '');
  });

  it('health failure', () => {
    let expected = '';
    let eventHandler: () => void = () => {};

    const request = { originalUrl: '/health' } as express.Request;
    const response = {
      on: (_event: string, func: () => void) => {
        eventHandler = func;
      },
      locals: {
        requestMetrics: RequestMetrics.startRequest(),
        logger: {
          error: (_message: string) => {
            expected = 'works!';
          },
        },
      },
      statusCode: 500,
    } as unknown as express.Response;

    onFinish(request, response, () => {});
    eventHandler();

    assert.equal(expected, 'works!');
  });
});
