"""Service module for handling exam evaluation and verification."""

import logging
from typing import Dict, List, Optional
from services.exam_service import ExamService
from services.ssh_service import SSHService

logger = logging.getLogger(__name__)


class EvaluationService:
    """Service class for managing exam evaluation and verification."""
    
    def __init__(self, exam_service: ExamService, ssh_service: SSHService):
        """
        Initialize EvaluationService.
        
        Args:
            exam_service: Instance of ExamService
            ssh_service: Instance of SSHService
        """
        self.exam_service = exam_service
        self.ssh_service = ssh_service
    
    def evaluate_exam(self) -> List[Dict]:
        """
        Evaluate all questions in the exam by running verification scripts.
        
        Returns:
            List of evaluation results for each question
        """
        # Load exam data
        exam_data = self.exam_service.load_exam_data()
        if not exam_data or not exam_data.get('success'):
            logger.error("Failed to load exam data")
            return []
        
        lab = exam_data.get('data', {}).get('lab', {})
        questions = lab.get('questions', [])
        
        results = []
        
        for question in questions:
            result = self._evaluate_question(question)
            if result:
                results.append(result)
        
        return results
    
    def _evaluate_question(self, question: Dict) -> Optional[Dict]:
        """
        Evaluate a single question by running its verification scripts.
        
        Args:
            question: Question data dictionary
            
        Returns:
            Evaluation result or None if question is not performance type
        """
        question_type = question.get('question_type')
        if question_type != 'performance':
            logger.info(f"Skipping non-performance question: {question.get('_id')}")
            return None
        
        performance_data = question.get('performance_data', {})
        verification_scripts = performance_data.get('verification_scripts', {})
        machine_hostname = performance_data.get('machine_hostname')
        
        if not machine_hostname or not verification_scripts:
            logger.warning(f"Missing verification data for question: {question.get('_id')}")
            return None
        
        # Evaluate verification steps
        steps_results = []
        verification_steps = verification_scripts.get('steps', [])
        
        for step in verification_steps:
            step_result = self._evaluate_verification_step(
                machine_hostname=machine_hostname,
                step=step
            )
            steps_results.append(step_result)
        
        # Build result object
        result = {
            'question_id': question.get('_id'),
            'question_order': question.get('question_order'),
            'question_title': question.get('question_title'),
            'question': question.get('question', ''),
            'answer_explanation': question.get('answer_explanation', ''),
            'performance_data': question.get('performance_data', {}),
            'steps': steps_results,
            'total_points_awarded': sum(s['points_awarded'] for s in steps_results),
            'total_possible_points': sum(s['points_possible'] for s in steps_results)
        }
        
        return result
    
    def _evaluate_verification_step(
        self,
        machine_hostname: str,
        step: Dict
    ) -> Dict:
        """
        Evaluate a single verification step by running its script.
        
        Args:
            machine_hostname: Remote machine hostname
            step: Verification step data
            
        Returns:
            Step evaluation result
        """
        order = step.get('order', 0)
        description = step.get('description', '')
        script_content = step.get('script_content', '')
        points_possible = step.get('points_awarded', 0)
        
        logger.info(f"Evaluating step {order} on {machine_hostname}: {description}")
        
        # Execute script with retries
        execution_result = self.ssh_service.execute_script(
            hostname=machine_hostname,
            script_content=script_content,
            max_retries=3
        )
        
        # Award full points if script succeeds (exit code 0), otherwise 0 points
        points_awarded = points_possible if execution_result['success'] else 0
        
        step_result = {
            'order': order,
            'description': description,
            'points_possible': points_possible,
            'points_awarded': points_awarded,
            'success': execution_result['success'],
            'attempts': execution_result['attempts'],
            'output': execution_result['output'],
            'error': execution_result['error'] if not execution_result['success'] else ''
        }
        
        return step_result
