const platformUtils = require('./platform-utils');

describe('Platform Detection', () => {
  describe('detectOS', () => {
    test('detects Windows correctly', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'win32' });
      
      expect(platformUtils.detectOS()).toBe('windows');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('detects macOS correctly', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'darwin' });
      
      expect(platformUtils.detectOS()).toBe('macos');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('detects Linux correctly', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'linux' });
      
      expect(platformUtils.detectOS()).toBe('linux');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns unknown for unsupported platforms', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'freebsd' });
      
      expect(platformUtils.detectOS()).toBe('unknown');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });
  });

  describe('detectArchitecture', () => {
    test('returns current architecture', () => {
      const arch = platformUtils.detectArchitecture();
      expect(typeof arch).toBe('string');
      expect(arch.length).toBeGreaterThan(0);
    });
  });

  describe('detectShell', () => {
    test('returns powershell for Windows', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'win32' });
      
      expect(platformUtils.detectShell()).toBe('powershell');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns bash or zsh for macOS', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'darwin' });
      
      const shell = platformUtils.detectShell();
      expect(['bash', 'zsh']).toContain(shell);
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns bash for Linux', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'linux' });
      
      expect(platformUtils.detectShell()).toBe('bash');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });
  });

  describe('getDefaultInstallPath', () => {
    test('returns Windows path for Windows', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'win32' });
      
      expect(platformUtils.getDefaultInstallPath()).toBe('C:\\Program Files\\DashCaddy');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns macOS path for macOS', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'darwin' });
      
      expect(platformUtils.getDefaultInstallPath()).toBe('/Applications/DashCaddy');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns Linux path for Linux', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'linux' });
      
      expect(platformUtils.getDefaultInstallPath()).toBe('/opt/dashcaddy');
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });
  });

  describe('Platform checks', () => {
    test('isWindows returns boolean', () => {
      expect(typeof platformUtils.isWindows()).toBe('boolean');
    });

    test('isMacOS returns boolean', () => {
      expect(typeof platformUtils.isMacOS()).toBe('boolean');
    });

    test('isLinux returns boolean', () => {
      expect(typeof platformUtils.isLinux()).toBe('boolean');
    });

    test('exactly one platform check returns true', () => {
      const checks = [
        platformUtils.isWindows(),
        platformUtils.isMacOS(),
        platformUtils.isLinux()
      ];
      const trueCount = checks.filter(Boolean).length;
      expect(trueCount).toBe(1);
    });
  });

  describe('getPlatformInfo', () => {
    test('returns complete platform information', () => {
      const info = platformUtils.getPlatformInfo();
      
      expect(info).toHaveProperty('os');
      expect(info).toHaveProperty('arch');
      expect(info).toHaveProperty('shell');
      expect(info).toHaveProperty('platform');
      expect(info).toHaveProperty('hostname');
      expect(info).toHaveProperty('homedir');
      expect(info).toHaveProperty('defaultInstallPath');
      expect(info).toHaveProperty('userInstallPath');
      
      expect(typeof info.os).toBe('string');
      expect(typeof info.arch).toBe('string');
      expect(typeof info.shell).toBe('string');
      expect(typeof info.hostname).toBe('string');
      expect(typeof info.homedir).toBe('string');
    });
  });

  describe('Path utilities', () => {
    test('normalizePath normalizes paths', () => {
      const normalized = platformUtils.normalizePath('/path//to///file');
      expect(normalized).not.toContain('//');
    });

    test('joinPath joins path segments', () => {
      const joined = platformUtils.joinPath('path', 'to', 'file');
      expect(joined).toContain('path');
      expect(joined).toContain('file');
    });

    test('getUserInstallPath returns path in home directory', () => {
      const userPath = platformUtils.getUserInstallPath();
      expect(userPath).toContain('DashCaddy');
    });
  });

  describe('getCommandExecution', () => {
    test('returns PowerShell execution for Windows', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'win32' });
      
      const exec = platformUtils.getCommandExecution('test command');
      expect(exec.shell).toBe('powershell.exe');
      expect(exec.args).toEqual(['-Command', 'test command']);
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });

    test('returns shell execution for Unix-like systems', () => {
      const originalPlatform = process.platform;
      Object.defineProperty(process, 'platform', { value: 'linux' });
      
      const exec = platformUtils.getCommandExecution('test command');
      expect(['bash', 'zsh']).toContain(exec.shell);
      expect(exec.args).toEqual(['-c', 'test command']);
      
      Object.defineProperty(process, 'platform', { value: originalPlatform });
    });
  });
});
