import { vi, type Mock } from 'vitest';
import { ConsoleLogger } from './ConsoleLogger';

describe('ConsoleLogger', () => {
  let logger: ConsoleLogger;
  let consoleDebugSpy: Mock;
  let consoleInfoSpy: Mock;
  let consoleWarnSpy: Mock;
  let consoleErrorSpy: Mock;

  beforeEach(() => {
    logger = new ConsoleLogger();
    consoleDebugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {});
    consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(() => {});
    consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
    consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
  });

  afterEach(() => {
    consoleDebugSpy.mockRestore();
    consoleInfoSpy.mockRestore();
    consoleWarnSpy.mockRestore();
    consoleErrorSpy.mockRestore();
  });

  it('should call console.debug with the correct arguments when debug is called', () => {
    const message = 'Debug message';
    const context = { key: 'value' };
    logger.debug(message, context);
    expect(consoleDebugSpy).toHaveBeenCalledTimes(1);
    expect(consoleDebugSpy).toHaveBeenCalledWith(message, context);
  });

  it('should call console.info with the correct arguments when info is called', () => {
    const message = 'Info message';
    const context = { key: 'value' };
    logger.info(message, context);
    expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
    expect(consoleInfoSpy).toHaveBeenCalledWith(message, context);
  });

  it('should call console.warn with the correct arguments when warn is called', () => {
    const message = 'Warn message';
    const context = { key: 'value' };
    logger.warn(message, context);
    expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
    expect(consoleWarnSpy).toHaveBeenCalledWith(message, context);
  });

  it('should call console.error with the correct arguments when error is called', () => {
    const message = 'Error message';
    const error = new Error('Something went wrong');
    const context = { key: 'value' };
    logger.error(message, error, context);
    expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
    expect(consoleErrorSpy).toHaveBeenCalledWith(message, error, context);
  });

});