import { spawn } from 'child_process';
import { promises as fs } from 'fs';
import { join, dirname, basename } from 'path';
import { homedir } from 'os';
import log from 'electron-log';
import { execAsync, getEnvWithPath } from '../utils/shell-utils';

export interface SshKeyStatus {
  keysExist: boolean;
  publicKeyPath?: string;
  privateKeyPath?: string;
  publicKeyContent?: string;
  valid: boolean;
  configExists?: boolean;
  configCorrect?: boolean;
  hasGitHub?: boolean;
  hasGerrit?: boolean;
  githubCorrect?: boolean;
  gerritCorrect?: boolean;
}

export interface SshKeyGenerateOptions {
  filename: string;
  passphrase: string;
}

export interface InstallResult {
  success: boolean;
  message: string;
}

/**
 * Check if SSH key pair exists and is valid
 */
export async function checkSshKeyStatus(publicKeyPath?: string): Promise<SshKeyStatus> {
  try {
    if (publicKeyPath) {
      // User provided a specific public key path
      const pubKeyExists = await fileExists(publicKeyPath);
      if (!pubKeyExists) {
        return {
          keysExist: false,
          valid: false
        };
      }

      // Check for corresponding private key
      const privateKeyPath = publicKeyPath.replace(/\.pub$/, '');
      const privKeyExists = await fileExists(privateKeyPath);

      if (!privKeyExists) {
        return {
          keysExist: true,
          publicKeyPath,
          privateKeyPath,
          valid: false
        };
      }

      // Read public key content
      const publicKeyContent = await fs.readFile(publicKeyPath, 'utf-8');

      // Validate key pair
      const isValid = await validateKeyPair(privateKeyPath, publicKeyPath);

      // Check SSH config status
      const configStatus = await checkSshConfig(privateKeyPath);

      return {
        keysExist: true,
        publicKeyPath,
        privateKeyPath,
        publicKeyContent: publicKeyContent.trim(),
        valid: isValid,
        configExists: configStatus.exists,
        configCorrect: configStatus.githubCorrect && configStatus.gerritCorrect,
        hasGitHub: configStatus.hasGitHub,
        hasGerrit: configStatus.hasGerrit,
        githubCorrect: configStatus.githubCorrect,
        gerritCorrect: configStatus.gerritCorrect
      };
    } else {
      // Check default SSH keys location
      const sshDir = join(homedir(), '.ssh');

      try {
        const files = await fs.readdir(sshDir);
        const pubFiles = files.filter(f => f.endsWith('.pub'));

        if (pubFiles.length === 0) {
          return {
            keysExist: false,
            valid: false
          };
        }

        // Check if we have at least one valid key pair
        for (const pubFile of pubFiles) {
          const publicKeyPath = join(sshDir, pubFile);
          const privateKeyPath = join(sshDir, pubFile.replace(/\.pub$/, ''));

          const privKeyExists = await fileExists(privateKeyPath);
          if (privKeyExists) {
            const publicKeyContent = await fs.readFile(publicKeyPath, 'utf-8');
            const isValid = await validateKeyPair(privateKeyPath, publicKeyPath);

            if (isValid) {
              // Check SSH config status
              const configStatus = await checkSshConfig(privateKeyPath);

              return {
                keysExist: true,
                publicKeyPath,
                privateKeyPath,
                publicKeyContent: publicKeyContent.trim(),
                valid: true,
                configExists: configStatus.exists,
                configCorrect: configStatus.githubCorrect && configStatus.gerritCorrect,
                hasGitHub: configStatus.hasGitHub,
                hasGerrit: configStatus.hasGerrit,
                githubCorrect: configStatus.githubCorrect,
                gerritCorrect: configStatus.gerritCorrect
              };
            }
          }
        }

        return {
          keysExist: true,
          valid: false
        };
      } catch (error) {
        log.info('SSH directory not found or empty');
        return {
          keysExist: false,
          valid: false
        };
      }
    }
  } catch (error: any) {
    log.error('Error checking SSH key status:', error);
    return {
      keysExist: false,
      valid: false
    };
  }
}

/**
 * Check if a file exists
 */
async function fileExists(path: string): Promise<boolean> {
  try {
    await fs.access(path);
    return true;
  } catch {
    return false;
  }
}

/**
 * Validate SSH key pair
 */
async function validateKeyPair(privateKeyPath: string, publicKeyPath: string): Promise<boolean> {
  try {
    // Check if both files exist
    const pubKeyExists = await fileExists(publicKeyPath);
    const privKeyExists = await fileExists(privateKeyPath);

    if (!pubKeyExists || !privKeyExists) {
      return false;
    }

    // Read and validate public key format
    const publicKeyContent = await fs.readFile(publicKeyPath, 'utf-8');
    const publicKeyLine = publicKeyContent.trim().split('\n')[0];

    // Validate public key format (should start with ssh-ed25519, ssh-rsa, ecdsa-sha2-nistp256, etc.)
    const validKeyTypes = ['ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521'];
    const hasValidKeyType = validKeyTypes.some(type => publicKeyLine.startsWith(type));

    if (!hasValidKeyType) {
      log.warn('Public key does not have a valid key type');
      return false;
    }

    // Check if private key file has proper permissions and is readable
    try {
      const privKeyStats = await fs.stat(privateKeyPath);

      // Private key should not be world-readable (permissions should be 600 or similar)
      // This is a basic check that the file exists and we can read its stats
      if (!privKeyStats.isFile()) {
        return false;
      }
    } catch (error) {
      log.warn('Failed to read private key stats:', error);
      return false;
    }

    // If both files exist and public key format is valid, consider it valid
    // We don't try to extract public key from private key as it may require passphrase
    return true;
  } catch (error) {
    log.warn('Failed to validate key pair:', error);
    return false;
  }
}

/**
 * Generate SSH key pair
 */
export async function generateSshKeys(options: SshKeyGenerateOptions): Promise<InstallResult> {
  try {
    const sshDir = join(homedir(), '.ssh');

    // Ensure .ssh directory exists
    try {
      await fs.mkdir(sshDir, { recursive: true, mode: 0o700 });
    } catch (error) {
      log.warn('.ssh directory already exists or could not be created:', error);
    }

    const keyPath = join(sshDir, options.filename);

    // Check if key already exists
    const keyExists = await fileExists(keyPath);
    if (keyExists) {
      return {
        success: false,
        message: 'SSH key with this filename already exists. Please choose a different name.'
      };
    }

    // Generate SSH key using ssh-keygen
    const command = `ssh-keygen -t ed25519 -f "${keyPath}" -N "${options.passphrase}"`;

    await execAsync(command);

    // Verify the keys were created
    const publicKeyPath = `${keyPath}.pub`;
    const pubKeyExists = await fileExists(publicKeyPath);
    const privKeyExists = await fileExists(keyPath);

    if (!pubKeyExists || !privKeyExists) {
      return {
        success: false,
        message: 'Failed to generate SSH keys. Please try again.'
      };
    }

    // Set proper permissions
    await fs.chmod(keyPath, 0o600);           // Private key
    await fs.chmod(publicKeyPath, 0o644);     // Public key
    await fs.chmod(sshDir, 0o700);            // .ssh directory

    log.info(`SSH keys generated successfully at ${keyPath}`);

    // Update SSH config with GitHub and Gerrit settings
    const configResult = await updateSshConfig(keyPath);
    if (!configResult.success) {
      log.warn('Failed to update SSH config:', configResult.message);
    } else {
      log.info('SSH config updated successfully');
    }

    return {
      success: true,
      message: `SSH keys generated successfully and SSH config updated`
    };
  } catch (error: any) {
    log.error('Error generating SSH keys:', error);
    return {
      success: false,
      message: `Failed to generate SSH keys: ${error.message}`
    };
  }
}

/**
 * Read public key content from file
 */
export async function readPublicKey(publicKeyPath: string): Promise<{ success: boolean; content?: string; message?: string }> {
  try {
    const content = await fs.readFile(publicKeyPath, 'utf-8');
    return {
      success: true,
      content: content.trim()
    };
  } catch (error: any) {
    log.error('Error reading public key:', error);
    return {
      success: false,
      message: `Failed to read public key: ${error.message}`
    };
  }
}

/**
 * Copy SSH key pair to ~/.ssh and set proper permissions
 * @param publicKeyPath Path to the public key file
 * @returns Result with information about what was done
 */
export async function copyAndSetupSshKeys(publicKeyPath: string): Promise<{
  success: boolean;
  message: string;
  publicKeyPath?: string;
  privateKeyPath?: string;
  copied?: boolean;
}> {
  try {
    const sshDir = join(homedir(), '.ssh');
    const privateKeyPath = publicKeyPath.replace(/\.pub$/, '');

    // Verify both keys exist
    const pubKeyExists = await fileExists(publicKeyPath);
    const privKeyExists = await fileExists(privateKeyPath);

    if (!pubKeyExists) {
      return {
        success: false,
        message: 'Public key file not found'
      };
    }

    if (!privKeyExists) {
      return {
        success: false,
        message: 'Private key file not found. Both public and private keys are required.'
      };
    }

    // Ensure ~/.ssh directory exists with proper permissions
    try {
      await fs.mkdir(sshDir, { recursive: true, mode: 0o700 });
    } catch (error) {
      // Directory might already exist, just ensure permissions
      await fs.chmod(sshDir, 0o700);
    }

    const publicKeyName = basename(publicKeyPath);
    const privateKeyName = basename(privateKeyPath);
    const targetPublicKeyPath = join(sshDir, publicKeyName);
    const targetPrivateKeyPath = join(sshDir, privateKeyName);

    // Check if the selected keys are already in ~/.ssh
    const alreadyInSshDir = dirname(publicKeyPath) === sshDir;
    let copied = false;

    if (!alreadyInSshDir) {
      // Copy both keys to ~/.ssh
      log.info(`Copying SSH keys to ${sshDir}`);
      await fs.copyFile(publicKeyPath, targetPublicKeyPath);
      await fs.copyFile(privateKeyPath, targetPrivateKeyPath);
      copied = true;
      log.info('SSH keys copied successfully');
    } else {
      log.info('Keys already in ~/.ssh, skipping copy');
    }

    // Always set proper permissions (even if keys were already in ~/.ssh)
    await fs.chmod(targetPrivateKeyPath, 0o600); // Private key: read/write for owner only
    await fs.chmod(targetPublicKeyPath, 0o644);  // Public key: read for all, write for owner
    await fs.chmod(sshDir, 0o700);               // .ssh directory: read/write/execute for owner only

    log.info('SSH key permissions set correctly');

    // Update SSH config with GitHub and Gerrit settings
    const configResult = await updateSshConfig(targetPrivateKeyPath);
    if (!configResult.success) {
      log.warn('Failed to update SSH config:', configResult.message);
    } else {
      log.info('SSH config updated successfully');
    }

    const message = copied
      ? `SSH keys copied to ${sshDir} and SSH config updated`
      : 'SSH key permissions verified and SSH config updated';

    return {
      success: true,
      message,
      publicKeyPath: targetPublicKeyPath,
      privateKeyPath: targetPrivateKeyPath,
      copied
    };
  } catch (error: any) {
    log.error('Error setting up SSH keys:', error);
    return {
      success: false,
      message: `Failed to setup SSH keys: ${error.message}`
    };
  }
}

/**
 * Update SSH config file with GitHub and Gerrit host configurations
 * @param privateKeyPath Path to the private key to use
 * @returns Result indicating success or failure
 */
export async function updateSshConfig(privateKeyPath: string): Promise<{
  success: boolean;
  message: string;
}> {
  try {
    const sshDir = join(homedir(), '.ssh');
    const configPath = join(sshDir, 'config');

    // Ensure ~/.ssh directory exists
    try {
      await fs.mkdir(sshDir, { recursive: true, mode: 0o700 });
    } catch (error) {
      await fs.chmod(sshDir, 0o700);
    }

    // Read existing config or create empty string
    let existingConfig = '';
    try {
      existingConfig = await fs.readFile(configPath, 'utf-8');
    } catch (error) {
      // File doesn't exist, will create new one
      log.info('SSH config file does not exist, creating new one');
    }

    // Parse existing config to check for our hosts
    const lines = existingConfig.split('\n');
    const hasGitHub = lines.some(line => line.trim().startsWith('Host github.com'));
    const hasGerrit = lines.some(line => line.trim().startsWith('Host gerrit.instructure.com'));

    // GitHub config block
    const githubConfig = `Host github.com
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ${privateKeyPath}`;

    // Gerrit config block
    const gerritConfig = `Host gerrit.instructure.com
  AddKeysToAgent yes
  UseKeychain yes
  HostName gerrit.instructure.com
  Port 29418
  IdentityFile ${privateKeyPath}`;

    let newConfig = existingConfig;

    // Remove existing GitHub config if present
    if (hasGitHub) {
      newConfig = removeHostBlock(newConfig, 'github.com');
    }

    // Remove existing Gerrit config if present
    if (hasGerrit) {
      newConfig = removeHostBlock(newConfig, 'gerrit.instructure.com');
    }

    // Add new configs at the beginning
    newConfig = `${githubConfig}\n\n${gerritConfig}\n\n${newConfig.trim()}\n`;

    // Write config file
    await fs.writeFile(configPath, newConfig, { mode: 0o600 });
    log.info('SSH config file updated successfully');

    return {
      success: true,
      message: 'SSH config updated with GitHub and Gerrit settings'
    };
  } catch (error: any) {
    log.error('Error updating SSH config:', error);
    return {
      success: false,
      message: `Failed to update SSH config: ${error.message}`
    };
  }
}

/**
 * Get Gerrit username from SSH config
 */
export async function getGerritUsername(): Promise<string | null> {
  try {
    const sshDir = join(homedir(), '.ssh');
    const configPath = join(sshDir, 'config');

    // Check if config exists
    try {
      await fs.access(configPath);
    } catch {
      log.info('SSH config file does not exist');
      return null;
    }

    // Read config file
    const config = await fs.readFile(configPath, 'utf-8');

    // Extract Gerrit block
    const gerritBlock = extractHostBlock(config, 'gerrit.instructure.com');

    if (!gerritBlock) {
      log.info('No Gerrit config found in SSH config');
      return null;
    }

    // Parse User field from the block
    const lines = gerritBlock.split('\n');
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('User ')) {
        const username = trimmed.substring(5).trim();
        log.info('Found Gerrit username in SSH config:', username);
        return username;
      }
    }

    log.info('No User field found in Gerrit config');
    return null;
  } catch (error: any) {
    log.error('Error getting Gerrit username:', error);
    return null;
  }
}

/**
 * Update Gerrit SSH config with username
 */
export async function updateGerritSshConfig(privateKeyPath: string, username: string): Promise<{
  success: boolean;
  message: string;
}> {
  try {
    const sshDir = join(homedir(), '.ssh');
    const configPath = join(sshDir, 'config');

    // Ensure ~/.ssh directory exists
    try {
      await fs.mkdir(sshDir, { recursive: true, mode: 0o700 });
    } catch (error) {
      await fs.chmod(sshDir, 0o700);
    }

    // Read existing config or create empty string
    let existingConfig = '';
    try {
      existingConfig = await fs.readFile(configPath, 'utf-8');
    } catch (error) {
      // File doesn't exist, will create new one
      log.info('SSH config file does not exist, creating new one');
    }

    // Remove existing Gerrit config if present
    const hasGerrit = existingConfig.split('\n').some(line => line.trim().startsWith('Host gerrit.instructure.com'));
    if (hasGerrit) {
      existingConfig = removeHostBlock(existingConfig, 'gerrit.instructure.com');
    }

    // Gerrit config block with username
    const gerritConfig = `Host gerrit.instructure.com
  AddKeysToAgent yes
  UseKeychain yes
  HostName gerrit.instructure.com
  Port 29418
  User ${username}
  IdentityFile ${privateKeyPath}`;

    // Add new Gerrit config at the beginning
    const newConfig = `${gerritConfig}\n\n${existingConfig.trim()}\n`;

    // Write config file
    await fs.writeFile(configPath, newConfig, { mode: 0o600 });
    log.info('SSH config file updated successfully with Gerrit username');

    return {
      success: true,
      message: 'SSH config updated with Gerrit settings and username'
    };
  } catch (error: any) {
    log.error('Error updating Gerrit SSH config:', error);
    return {
      success: false,
      message: `Failed to update SSH config: ${error.message}`
    };
  }
}

/**
 * Remove a host block from SSH config
 */
function removeHostBlock(config: string, hostname: string): string {
  const lines = config.split('\n');
  const result: string[] = [];
  let inHostBlock = false;
  let skipUntilNextHost = false;

  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    const trimmed = line.trim();

    // Check if this is a Host line
    if (trimmed.startsWith('Host ')) {
      // If we were skipping a block, stop skipping
      if (skipUntilNextHost) {
        skipUntilNextHost = false;
      }

      // Check if this is the host we want to remove
      if (trimmed === `Host ${hostname}`) {
        skipUntilNextHost = true;
        continue; // Skip this line
      }
    }

    // Skip lines that are part of the block we're removing
    if (skipUntilNextHost && (line.startsWith('  ') || line.startsWith('\t') || trimmed === '')) {
      continue;
    }

    // If we hit a non-indented line after skipping, stop skipping
    if (skipUntilNextHost && !line.startsWith('  ') && !line.startsWith('\t') && trimmed !== '') {
      skipUntilNextHost = false;
    }

    if (!skipUntilNextHost) {
      result.push(line);
    }
  }

  return result.join('\n');
}

/**
 * Check if SSH config has proper GitHub and Gerrit configurations
 * @param privateKeyPath Expected private key path
 * @returns Status of SSH config
 */
export async function checkSshConfig(privateKeyPath: string): Promise<{
  exists: boolean;
  hasGitHub: boolean;
  hasGerrit: boolean;
  githubCorrect: boolean;
  gerritCorrect: boolean;
}> {
  try {
    const sshDir = join(homedir(), '.ssh');
    const configPath = join(sshDir, 'config');

    const configExists = await fileExists(configPath);
    if (!configExists) {
      return {
        exists: false,
        hasGitHub: false,
        hasGerrit: false,
        githubCorrect: false,
        gerritCorrect: false
      };
    }

    const config = await fs.readFile(configPath, 'utf-8');
    const lines = config.split('\n').map(l => l.trim());

    // Check GitHub config
    const githubHostIndex = lines.findIndex(l => l.startsWith('Host github.com'));
    let hasGitHub = githubHostIndex !== -1;
    let githubCorrect = false;

    if (hasGitHub) {
      // Check if the config block has the required settings
      const githubBlock = extractHostBlock(config, 'github.com');
      githubCorrect =
        githubBlock.includes('AddKeysToAgent yes') &&
        githubBlock.includes('UseKeychain yes') &&
        githubBlock.includes(`IdentityFile ${privateKeyPath}`);
    }

    // Check Gerrit config
    const gerritHostIndex = lines.findIndex(l => l.startsWith('Host gerrit.instructure.com'));
    let hasGerrit = gerritHostIndex !== -1;
    let gerritCorrect = false;

    if (hasGerrit) {
      const gerritBlock = extractHostBlock(config, 'gerrit.instructure.com');
      gerritCorrect =
        gerritBlock.includes('AddKeysToAgent yes') &&
        gerritBlock.includes('UseKeychain yes') &&
        gerritBlock.includes('HostName gerrit.instructure.com') &&
        gerritBlock.includes('Port 29418') &&
        gerritBlock.includes(`IdentityFile ${privateKeyPath}`);
    }

    return {
      exists: true,
      hasGitHub,
      hasGerrit,
      githubCorrect,
      gerritCorrect
    };
  } catch (error: any) {
    log.error('Error checking SSH config:', error);
    return {
      exists: false,
      hasGitHub: false,
      hasGerrit: false,
      githubCorrect: false,
      gerritCorrect: false
    };
  }
}

/**
 * Extract a host block from SSH config
 */
function extractHostBlock(config: string, hostname: string): string {
  const lines = config.split('\n');
  const result: string[] = [];
  let inBlock = false;

  for (const line of lines) {
    const trimmed = line.trim();

    if (trimmed.startsWith('Host ')) {
      if (trimmed === `Host ${hostname}`) {
        inBlock = true;
        result.push(line);
      } else if (inBlock) {
        // Hit another Host, stop collecting
        break;
      }
    } else if (inBlock) {
      if (line.startsWith('  ') || line.startsWith('\t') || trimmed === '') {
        result.push(line);
      } else {
        // Non-indented line, end of block
        break;
      }
    }
  }

  return result.join('\n');
}

/**
 * Test SSH connection to GitHub
 * @param privateKeyPath Optional path to private key to use for authentication
 * @returns Promise with connection status
 */
export async function testGitHubSshConnection(privateKeyPath?: string): Promise<{
  connected: boolean;
  message: string;
  username?: string;
}> {
  try {
    log.info('Testing GitHub SSH connection...', { privateKeyPath });

    // Build SSH command with explicit private key if provided
    const keyOption = privateKeyPath ? `-i "${privateKeyPath}"` : '';
    const sshCommand = `ssh -T ${keyOption} -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 git@github.com`.replace(/\s+/g, ' ').trim();

    // Run ssh -T git@github.com with options to:
    // - i: Explicitly specify private key to use
    // - IdentitiesOnly=yes: Only use specified identity, don't try other keys
    // - BatchMode=yes: Disable interactive prompts, fail fast
    // - StrictHostKeyChecking=accept-new: Accept new host keys automatically (first connection)
    // - ConnectTimeout=10: Timeout after 10 seconds
    // This command will exit with code 1 on success (this is expected behavior from GitHub)
    // The output should contain "Hi <username>! You've successfully authenticated"
    const { stdout, stderr } = await execAsync(sshCommand, {
      timeout: 15000, // 15 second timeout (slightly longer than ConnectTimeout)
      env: getEnvWithPath()
    });

    const output = stdout + stderr;
    log.info('GitHub SSH test output:', output);

    // GitHub sends the success message to stderr
    // Look for the success message
    if (output.includes('successfully authenticated')) {
      // Extract username from message like "Hi username! You've successfully authenticated"
      const match = output.match(/Hi ([^!]+)!/);
      const username = match ? match[1] : undefined;

      return {
        connected: true,
        message: 'Successfully authenticated with GitHub',
        username
      };
    }

    return {
      connected: false,
      message: 'Authentication failed - SSH key may not be added to GitHub'
    };
  } catch (error: any) {
    // SSH commands return non-zero exit codes even on success (this is expected)
    // We need to check the actual message content to determine if auth succeeded
    const errorMessage = error.message || '';
    const stderr = error.stderr || '';
    const stdout = error.stdout || '';
    const fullOutput = errorMessage + stderr + stdout;

    log.info('GitHub SSH test error output:', fullOutput);

    // Check if it's the expected "error" with success message
    if (fullOutput.includes('successfully authenticated')) {
      const match = fullOutput.match(/Hi ([^!]+)!/);
      const username = match ? match[1] : undefined;

      log.info('GitHub SSH connection successful');
      return {
        connected: true,
        message: 'Successfully authenticated with GitHub',
        username
      };
    }

    // Check for common error messages
    if (fullOutput.includes('Permission denied')) {
      return {
        connected: false,
        message: 'Permission denied - SSH key not added to GitHub or invalid'
      };
    }

    if (fullOutput.includes('Could not resolve hostname')) {
      return {
        connected: false,
        message: 'Could not connect to GitHub - check internet connection'
      };
    }

    if (fullOutput.includes('Host key verification failed') || fullOutput.includes('Are you sure you want to continue connecting')) {
      return {
        connected: false,
        message: 'Host key verification failed - SSH configuration issue'
      };
    }

    log.error('GitHub SSH connection failed:', error);
    return {
      connected: false,
      message: 'Failed to test GitHub SSH connection'
    };
  }
}

/**
 * Test SSH connection to Gerrit
 * @param privateKeyPath Optional path to private key to use for authentication
 * @returns Promise with connection status
 */
export async function testGerritSshConnection(privateKeyPath?: string): Promise<{
  connected: boolean;
  message: string;
  username?: string;
}> {
  try {
    log.info('Testing Gerrit SSH connection...', { privateKeyPath });

    // Build SSH command with explicit private key if provided
    const keyOption = privateKeyPath ? `-i "${privateKeyPath}"` : '';
    const sshCommand = `ssh -T ${keyOption} -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 gerrit.instructure.com`.replace(/\s+/g, ' ').trim();

    // Run ssh -T gerrit.instructure.com with options to:
    // - i: Explicitly specify private key to use
    // - IdentitiesOnly=yes: Only use specified identity, don't try other keys
    // - BatchMode=yes: Disable interactive prompts, fail fast
    // - StrictHostKeyChecking=accept-new: Accept new host keys automatically (first connection)
    // - ConnectTimeout=10: Timeout after 10 seconds
    const { stdout, stderr } = await execAsync(sshCommand, {
      timeout: 15000, // 15 second timeout (slightly longer than ConnectTimeout)
      env: getEnvWithPath()
    });

    const output = stdout + stderr;
    log.info('Gerrit SSH test output:', output);

    // Gerrit typically sends a welcome message on successful authentication
    // The message format may vary, but typically includes "gerrit" and indicates successful auth
    if (output.includes('Welcome') || output.includes('gerrit') || output.includes('****')) {
      return {
        connected: true,
        message: 'Successfully authenticated with Gerrit'
      };
    }

    return {
      connected: false,
      message: 'Authentication failed - SSH key may not be added to Gerrit'
    };
  } catch (error: any) {
    // SSH commands return non-zero exit codes even on success (this is expected)
    // We need to check the actual message content to determine if auth succeeded
    const errorMessage = error.message || '';
    const stderr = error.stderr || '';
    const stdout = error.stdout || '';
    const fullOutput = errorMessage + stderr + stdout;

    log.info('Gerrit SSH test error output:', fullOutput);

    // Check if the error output contains a welcome/success message
    if (fullOutput.includes('Welcome to Gerrit') || fullOutput.includes('successfully connected over SSH')) {
      log.info('Gerrit SSH connection successful');
      return {
        connected: true,
        message: 'Successfully authenticated with Gerrit'
      };
    }

    // Check for common error messages
    if (fullOutput.includes('Permission denied')) {
      return {
        connected: false,
        message: 'Permission denied - SSH key not added to Gerrit or invalid'
      };
    }

    if (fullOutput.includes('Could not resolve hostname')) {
      return {
        connected: false,
        message: 'Could not connect to Gerrit - check internet connection or VPN'
      };
    }

    if (fullOutput.includes('Host key verification failed') || fullOutput.includes('Are you sure you want to continue connecting')) {
      return {
        connected: false,
        message: 'Host key verification failed - SSH configuration issue'
      };
    }

    log.error('Gerrit SSH connection failed:', error);
    return {
      connected: false,
      message: 'Failed to test Gerrit SSH connection'
    };
  }
}
