import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { Logger, createLogger, logger } from './logger';
describe('Logger', () => {
    let consoleSpy;
    beforeEach(() => {
        consoleSpy = {
            debug: vi.spyOn(console, 'debug').mockImplementation(() => { }),
            info: vi.spyOn(console, 'info').mockImplementation(() => { }),
            warn: vi.spyOn(console, 'warn').mockImplementation(() => { }),
            error: vi.spyOn(console, 'error').mockImplementation(() => { }),
        };
    });
    afterEach(() => {
        vi.restoreAllMocks();
    });
    describe('log levels', () => {
        it('should not log debug when level is info', () => {
            const log = new Logger({ level: 'info' });
            log.debug('test message');
            expect(consoleSpy.debug).not.toHaveBeenCalled();
        });
        it('should log info when level is info', () => {
            const log = new Logger({ level: 'info' });
            log.info('test message');
            expect(consoleSpy.info).toHaveBeenCalled();
        });
        it('should log warn when level is info', () => {
            const log = new Logger({ level: 'info' });
            log.warn('test message');
            expect(consoleSpy.warn).toHaveBeenCalled();
        });
        it('should log error when level is info', () => {
            const log = new Logger({ level: 'info' });
            log.error('test message');
            expect(consoleSpy.error).toHaveBeenCalled();
        });
        it('should log all levels when level is debug', () => {
            const log = new Logger({ level: 'debug' });
            log.debug('debug message');
            log.info('info message');
            log.warn('warn message');
            log.error('error message');
            expect(consoleSpy.debug).toHaveBeenCalled();
            expect(consoleSpy.info).toHaveBeenCalled();
            expect(consoleSpy.warn).toHaveBeenCalled();
            expect(consoleSpy.error).toHaveBeenCalled();
        });
    });
    describe('prefix', () => {
        it('should include prefix in log message', () => {
            const log = new Logger({ level: 'info', prefix: 'test-module' });
            log.info('test message');
            expect(consoleSpy.info).toHaveBeenCalledWith(expect.stringContaining('[test-module]'));
        });
    });
    describe('timestamp', () => {
        it('should include timestamp by default', () => {
            const log = new Logger({ level: 'info' });
            log.info('test message');
            expect(consoleSpy.info).toHaveBeenCalledWith(expect.stringMatching(/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/));
        });
    });
    describe('child logger', () => {
        it('should create child logger with combined prefix', () => {
            const parentLog = new Logger({ level: 'info', prefix: 'parent' });
            const childLog = parentLog.child('child');
            childLog.info('test message');
            expect(consoleSpy.info).toHaveBeenCalledWith(expect.stringContaining('[parent:child]'));
        });
    });
    describe('object formatting', () => {
        it('should format objects in log message', () => {
            const log = new Logger({ level: 'info' });
            log.info('test', { key: 'value' });
            expect(consoleSpy.info).toHaveBeenCalledWith(expect.stringContaining('"key"'));
        });
    });
});
describe('createLogger', () => {
    it('should create logger with prefix', () => {
        const log = createLogger('test-prefix');
        expect(log).toBeInstanceOf(Logger);
    });
});
describe('default logger', () => {
    it('should export logger methods', () => {
        expect(typeof logger.debug).toBe('function');
        expect(typeof logger.info).toBe('function');
        expect(typeof logger.warn).toBe('function');
        expect(typeof logger.error).toBe('function');
        expect(typeof logger.child).toBe('function');
    });
});
