import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { BrowserModeConfigLoader } from '@core/automation/infrastructure/config/BrowserModeConfig';

/**
 * Unit tests for BrowserModeConfig - GREEN PHASE
 *
 * Tests for browser mode configuration with runtime control in development mode.
 */

describe('BrowserModeConfig - GREEN Phase', () => {
  const originalEnv = process.env;

  beforeEach(() => {
    process.env = { ...originalEnv };
    delete (process.env as unknown).NODE_ENV;
  });

  afterEach(() => {
    process.env = originalEnv;
  });

  describe('Development Mode with Runtime Control', () => {
    it('should default to headless in development mode', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.mode).toBe('headless'); // Changed from 'headed'
      expect(config.source).toBe('GUI');
    });

    it('should allow runtime switch to headless mode in development', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      loader.setDevelopmentMode('headless');
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('GUI');
    });

    it('should allow runtime switch to headed mode in development', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      loader.setDevelopmentMode('headed');
      const config = loader.load();
      
      expect(config.mode).toBe('headed');
      expect(config.source).toBe('GUI');
    });

    it('should persist runtime setting across multiple load() calls', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      loader.setDevelopmentMode('headless');
      
      const config1 = loader.load();
      const config2 = loader.load();
      
      expect(config1.mode).toBe('headless');
      expect(config2.mode).toBe('headless');
    });

    it('should return current development mode via getter', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      expect(loader.getDevelopmentMode()).toBe('headless');
      
      loader.setDevelopmentMode('headless');
      expect(loader.getDevelopmentMode()).toBe('headless');
    });
  });

  describe('Production Mode', () => {
    it('should use headless mode when NODE_ENV=production', () => {
      (process.env as unknown).NODE_ENV = 'production';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });

    it('should ignore setDevelopmentMode in production', () => {
      (process.env as unknown).NODE_ENV = 'production';
      
      const loader = new BrowserModeConfigLoader();
      loader.setDevelopmentMode('headed');
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });
  });

  describe('Test Mode', () => {
    it('should use headless mode when NODE_ENV=test', () => {
      (process.env as unknown).NODE_ENV = 'test';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });

    it('should ignore setDevelopmentMode in test mode', () => {
      (process.env as unknown).NODE_ENV = 'test';
      
      const loader = new BrowserModeConfigLoader();
      loader.setDevelopmentMode('headed');
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });
  });

  describe('Default Mode', () => {
    it('should default to headless mode when NODE_ENV is not set', () => {
      delete (process.env as unknown).NODE_ENV;
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });

    it('should use headless mode for any non-development NODE_ENV value', () => {
      (process.env as unknown).NODE_ENV = 'staging';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.mode).toBe('headless');
      expect(config.source).toBe('NODE_ENV');
    });
  });

  describe('Source Tracking', () => {
    it('should report GUI as source in development mode', () => {
      (process.env as unknown).NODE_ENV = 'development';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.source).toBe('GUI');
    });

    it('should report NODE_ENV as source in production mode', () => {
      (process.env as unknown).NODE_ENV = 'production';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.source).toBe('NODE_ENV');
    });

    it('should report NODE_ENV as source in test mode', () => {
      (process.env as unknown).NODE_ENV = 'test';
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.source).toBe('NODE_ENV');
    });

    it('should report NODE_ENV as source when NODE_ENV is not set', () => {
      delete (process.env as unknown).NODE_ENV;
      
      const loader = new BrowserModeConfigLoader();
      const config = loader.load();
      
      expect(config.source).toBe('NODE_ENV');
    });
  });
});