/**
 * Logger Test Setup
 *
 * Setup file specific to Logger library tests.
 * Provides utilities and mocks for testing logging operations.
 */

import { afterAll, afterEach, beforeAll } from 'bun:test';
import { shutdownLoggers } from '../src';

// Store original console methods
const originalConsole = {
  log: console.log,
  info: console.info,
  warn: console.warn,
  error: console.error,
  debug: console.debug,
};

// Create a test logger helper
export const loggerTestHelpers = {
  /**
   * Mock Loki transport
   */
  mockLokiTransport: () => ({
    on: () => {},
    write: () => {},
  }),
  /**
   * Create a mock Hono context for middleware tests
   */ createHonoContextMock: (options: any = {}) => {
    // Default path and method
    const path = options.path || '/test';
    const method = options.method || 'GET';

    // Create request headers
    const headerEntries = Object.entries(options.req?.headers || {});
    const headerMap = new Map(headerEntries);
    const rawHeaders = new Headers();
    headerEntries.forEach(([key, value]) => rawHeaders.set(key, value as string));

    // Create request with standard properties needed for middleware
    const req = {
      method,
      url: `http://localhost${path}`,
      path,
      raw: {
        url: `http://localhost${path}`,
        method,
        headers: rawHeaders,
      },
      query: {},
      param: () => undefined,
      header: (name: string) => rawHeaders.get(name.toLowerCase()),
      headers: headerMap,
      ...options.req,
    };

    // Create mock response
    const res = {
      status: 200,
      statusText: 'OK',
      body: null,
      headers: new Map(),
      clone: function () {
        return { ...this, text: async () => JSON.stringify(this.body) };
      },
      text: async () => JSON.stringify(res.body),
      ...options.res,
    };

    // Create context with all required Hono methods
    const c: any = {
      req,
      env: {},
      res,
      header: (name: string, value: string) => {
        c.res.headers.set(name.toLowerCase(), value);
        return c;
      },
      get: (key: string) => c[key],
      set: (key: string, value: any) => {
        c[key] = value;
        return c;
      },
      status: (code: number) => {
        c.res.status = code;
        return c;
      },
      json: (body: any) => {
        c.res.body = body;
        return c;
      },
      executionCtx: {
        waitUntil: (fn: Function) => {
          fn();
        },
      },
    };

    return c;
  },

  /**
   * Create a mock Next function for middleware tests
   */
  createNextMock: () => {
    return async () => {
      // Do nothing, simulate middleware completion
      return;
    };
  },
};

// Setup environment before tests
beforeAll(() => {
  // Don't let real logs through during tests
  console.log = () => {};
  console.info = () => {};
  console.warn = () => {};
  console.error = () => {};
  console.debug = () => {};

  // Override NODE_ENV for tests
  process.env.NODE_ENV = 'test';

  // Disable real logging during tests
  process.env.LOG_LEVEL = 'silent';
  process.env.LOG_CONSOLE = 'false';
  process.env.LOG_FILE = 'false';

  // Mock Loki config to prevent real connections
  process.env.LOKI_HOST = '';
  process.env.LOKI_URL = '';
});

// Clean up after each test
afterEach(async () => {
  // Clear logger cache to prevent state pollution between tests
  await shutdownLoggers();
});

// Restore everything after tests
afterAll(() => {
  console.log = originalConsole.log;
  console.info = originalConsole.info;
  console.warn = originalConsole.warn;
  console.error = originalConsole.error;
  console.debug = originalConsole.debug;
});
