"""Service module for handling SSH operations."""

import subprocess
import logging
from typing import Dict, Optional

logger = logging.getLogger(__name__)


class SSHService:
    """Service class for managing SSH operations."""
    
    def __init__(self):
        """Initialize SSHService."""
        pass
    
    def execute_script(
        self,
        hostname: str,
        script_content: str,
        max_retries: int = 3
    ) -> Dict[str, any]:
        """
        Execute a script on a remote machine via SSH.
        
        Args:
            hostname: Remote machine hostname
            script_content: Full script content to execute
            max_retries: Maximum number of retry attempts
            
        Returns:
            Dictionary containing execution results
        """
        result = {
            'success': False,
            'output': '',
            'error': '',
            'exit_code': -1,
            'attempts': 0
        }
        
        for attempt in range(1, max_retries + 1):
            result['attempts'] = attempt
            
            try:
                # Execute SSH command with script
                ssh_command = [
                    'ssh',
                    '-o', 'StrictHostKeyChecking=no',
                    '-o', 'ConnectTimeout=10',
                    hostname,
                    'bash', '-s'
                ]
                
                # Run the command with the script as stdin
                process = subprocess.Popen(
                    ssh_command,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                    text=True
                )
                
                stdout, stderr = process.communicate(input=script_content, timeout=120)
                
                result['exit_code'] = process.returncode
                result['output'] = stdout
                result['error'] = stderr
                
                # Command executed successfully (regardless of exit code)
                # Set success flag based on exit code
                if process.returncode == 0:
                    result['success'] = True
                    logger.info(f"Script executed successfully on {hostname} (attempt {attempt})")
                else:
                    logger.warning(
                        f"Script executed but returned non-zero exit code on {hostname} "
                        f"(attempt {attempt}): exit code {process.returncode}"
                    )
                
                # Break here - command was executed, don't retry
                # (even if exit code was non-zero, the command ran)
                break
                    
            except subprocess.TimeoutExpired:
                result['error'] = 'Script execution timeout (120s)'
                logger.error(f"Timeout executing script on {hostname} (attempt {attempt})")
                # Continue to retry on timeout
                if attempt < max_retries:
                    logger.info(f"Retrying due to timeout... (attempt {attempt + 1}/{max_retries})")
                    
            except Exception as e:
                result['error'] = str(e)
                logger.error(f"Error executing script on {hostname} (attempt {attempt}): {e}")
                # Continue to retry on connection/execution errors
                if attempt < max_retries:
                    logger.info(f"Retrying due to error... (attempt {attempt + 1}/{max_retries})")
        
        return result

