export type OSFamily = 'windows' | 'linux' | 'macos' | 'unix' | 'unknown';
export type ProtocolType = 'rdp' | 'vnc' | 'ssh' | 'telnet';

export interface ProtocolOption {
  value: ProtocolType;
  label: string;
  description: string;
  icon: string;
  defaultPort: number;
  requirements?: readonly string[];
}

export interface OSInfo {
  family: OSFamily;
  version?: string;
  architecture?: string;
}

export interface CompatibilityInfo {
  recommendations: readonly string[];
  warnings: readonly string[];
  tips: readonly string[];
}

export interface PortValidation {
  valid: boolean;
  suggestion?: number;
}

const VERSION_PATTERNS = {
  WINDOWS: [
    /windows\s*(\d+)/i,
    /windows\s*(xp|vista|7|8|8\.1|10|11)/i,
    /windows\s*(server\s*\d+)/i,
  ],
  LINUX: [
    /ubuntu\s*(\d+\.\d+)/i,
    /debian\s*(\d+)/i,
    /centos\s*(\d+)/i,
    /rhel\s*(\d+)/i,
  ],
  MACOS: [
    /macos\s*(\d+\.\d+)/i,
    /mac\s*os\s*(\d+\.\d+)/i,
  ],
} as const;

export class ProtocolHelper {
  private static readonly PROTOCOLS: Readonly<Record<ProtocolType, ProtocolOption>> = {
    rdp: {
      value: 'rdp',
      label: 'RDP',
      description: 'Remote Desktop Protocol - Native Windows remote access',
      icon: '🖥️',
      defaultPort: 3389,
      requirements: ['Windows OS', 'Remote Desktop enabled']
    },
    vnc: {
      value: 'vnc',
      label: 'VNC',
      description: 'Virtual Network Computing - Cross-platform remote desktop',
      icon: '🖱️',
      defaultPort: 5900,
      requirements: ['VNC Server installed']
    },
    ssh: {
      value: 'ssh',
      label: 'SSH',
      description: 'Secure Shell - Command line access',
      icon: '⌨️',
      defaultPort: 22,
      requirements: ['SSH Server enabled']
    },
    telnet: {
      value: 'telnet',
      label: 'Telnet',
      description: 'Telnet - Legacy command line access (not secure)',
      icon: '📡',
      defaultPort: 23,
      requirements: ['Telnet Server enabled']
    }
  };

  /**
   * Parse OS string into structured information
   */
  static parseOS(osString: string): OSInfo {
    const os = osString.toLowerCase();
    
    if (os.includes('windows')) {
      return {
        family: 'windows',
        version: this.extractWindowsVersion(os),
        architecture: this.extractArchitecture(os)
      };
    }
    
    if (os.includes('ubuntu') || os.includes('debian') || os.includes('centos') || 
        os.includes('rhel') || os.includes('linux')) {
      return {
        family: 'linux',
        version: this.extractLinuxVersion(os),
        architecture: this.extractArchitecture(os)
      };
    }
    
    if (os.includes('macos') || os.includes('mac os') || os.includes('darwin')) {
      return {
        family: 'macos',
        version: this.extractMacVersion(os),
        architecture: this.extractArchitecture(os)
      };
    }
    
    if (os.includes('unix') || os.includes('solaris') || os.includes('aix')) {
      return {
        family: 'unix',
        architecture: this.extractArchitecture(os)
      };
    }
    
    return { family: 'unknown' };
  }

  /**
   * Get recommended protocols for given OS
   */
  static getRecommendedProtocols(osInfo: OSInfo): ProtocolOption[] {
    const protocols: ProtocolOption[] = [];
    
    switch (osInfo.family) {
      case 'windows':
        // Windows: RDP first, then VNC and SSH
        protocols.push(
          this.PROTOCOLS.rdp,
          this.PROTOCOLS.vnc,
          this.PROTOCOLS.ssh
        );
        break;
        
      case 'linux':
        // Linux: SSH first, then VNC
        protocols.push(
          this.PROTOCOLS.ssh,
          this.PROTOCOLS.vnc
        );
        // For Linux with GUI, add Telnet as fallback
        if (this.hasDesktopEnvironment(osInfo)) {
          protocols.push(this.PROTOCOLS.telnet);
        }
        break;
        
      case 'macos':
        // macOS: SSH first, VNC second
        protocols.push(
          this.PROTOCOLS.ssh,
          this.PROTOCOLS.vnc
        );
        break;
        
      case 'unix':
        // Unix systems: SSH and Telnet
        protocols.push(
          this.PROTOCOLS.ssh,
          this.PROTOCOLS.telnet
        );
        break;
        
      default:
        // Unknown OS: show all options
        protocols.push(
          this.PROTOCOLS.ssh,
          this.PROTOCOLS.vnc,
          this.PROTOCOLS.rdp,
          this.PROTOCOLS.telnet
        );
    }
    
    return protocols;
  }

  /**
   * Get default protocol for OS
   */
  static getDefaultProtocol(osInfo: OSInfo): ProtocolOption {
    const recommended = this.getRecommendedProtocols(osInfo);
    return recommended[0] || this.PROTOCOLS.ssh;
  }

  /**
   * Get additional compatibility information
   */
  static getCompatibilityInfo(osInfo: OSInfo): CompatibilityInfo {
    const info: {
      recommendations: string[];
      warnings: string[];
      tips: string[];
    } = {
      recommendations: [],
      warnings: [],
      tips: [],
    };

    switch (osInfo.family) {
      case 'windows':
        info.recommendations.push('RDP provides the best experience for Windows machines');
        info.tips.push('Ensure Remote Desktop is enabled in Windows settings');
        if (osInfo.version && osInfo.version.includes('home')) {
          info.warnings.push('Windows Home editions may have limited RDP support');
        }
        break;
        
      case 'linux':
        info.recommendations.push('SSH is the most reliable option for Linux systems');
        info.tips.push('VNC requires a desktop environment and VNC server installation');
        break;
        
      case 'macos':
        info.recommendations.push('SSH works best for macOS command line access');
        info.tips.push('Enable "Remote Login" in System Preferences for SSH');
        info.warnings.push('VNC may require additional setup on macOS');
        break;
        
      default:
        info.tips.push('Try SSH first as it\'s widely supported');
    }

    return info;
  }

  /**
   * Validate port for protocol
   */
  static validatePort(protocol: string, port: number): PortValidation {
    const protocolInfo = this.PROTOCOLS[protocol as ProtocolType];
    if (!protocolInfo) {
      return { valid: false };
    }

    if (port === protocolInfo.defaultPort) {
      return { valid: true };
    }

    const alternativePorts = this.getAlternativePorts(protocol);
    if (alternativePorts.includes(port)) {
      return { valid: true };
    }

    return {
      valid: true,
      suggestion: protocolInfo.defaultPort,
    };
  }

  private static extractVersion(os: string, patterns: readonly RegExp[]): string {
    for (const pattern of patterns) {
      const match = os.match(pattern);
      if (match?.[1]) return match[1];
    }
    return '';
  }

  private static extractWindowsVersion(os: string): string {
    return this.extractVersion(os, VERSION_PATTERNS.WINDOWS);
  }

  private static extractLinuxVersion(os: string): string {
    return this.extractVersion(os, VERSION_PATTERNS.LINUX);
  }

  private static extractMacVersion(os: string): string {
    return this.extractVersion(os, VERSION_PATTERNS.MACOS);
  }

  private static extractArchitecture(os: string): string {
    if (os.includes('x64') || os.includes('x86_64') || os.includes('amd64')) {
      return 'x64';
    }
    if (os.includes('x86') || os.includes('i386')) {
      return 'x86';
    }
    if (os.includes('arm64') || os.includes('aarch64')) {
      return 'arm64';
    }
    if (os.includes('arm')) {
      return 'arm';
    }
    return '';
  }

  private static hasDesktopEnvironment(osInfo: OSInfo): boolean {
    // Simple heuristic for detecting GUI presence
    return osInfo.version?.includes('desktop') || 
           osInfo.version?.includes('gnome') || 
           osInfo.version?.includes('kde') ||
           !osInfo.version?.includes('server');
  }

  private static getAlternativePorts(protocol: string): number[] {
    const alternatives: Record<string, number[]> = {
      rdp: [3389, 3390, 3391],
      vnc: [5900, 5901, 5902, 5903],
      ssh: [22, 2222, 2022],
      telnet: [23, 2323]
    };
    
    return alternatives[protocol] || [];
  }
} 