# Copyright (c) 2025 Patrick Motsch
# All rights reserved.
# validator.py
# Validation logic for workflows

import logging
from typing import Dict, Any, List

logger = logging.getLogger(__name__)

class WorkflowValidator:
    """Handles validation of workflow components"""
    
    def __init__(self, services):
        self.services = services
    
    def validateTask(self, taskPlan: Dict[str, Any]) -> bool:
        """Validate task plan structure"""
        try:
            if not isinstance(taskPlan, dict):
                logger.error("Task plan is not a dictionary")
                return False
                
            if 'tasks' not in taskPlan or not isinstance(taskPlan['tasks'], list):
                logger.error(f"Task plan missing 'tasks' field or not a list. Found: {type(taskPlan.get('tasks', 'MISSING'))}")
                return False
                
            # First pass: collect all task IDs to validate dependencies
            taskIds = set()
            for task in taskPlan['tasks']:
                if not isinstance(task, dict):
                    logger.error(f"Task is not a dictionary: {type(task)}")
                    return False
                if 'id' not in task:
                    logger.error(f"Task missing 'id' field: {task}")
                    return False
                taskIds.add(task['id'])
            
            # Second pass: validate each task
            for i, task in enumerate(taskPlan['tasks']):
                if not isinstance(task, dict):
                    logger.error(f"Task {i} is not a dictionary: {type(task)}")
                    return False
                    
                requiredFields = ['id', 'objective', 'successCriteria']
                missingFields = [field for field in requiredFields if field not in task]
                if missingFields:
                    logger.error(f"Task {i} missing required fields: {missingFields}")
                    return False
                    
                # Check for duplicate IDs (shouldn't happen after first pass, but safety check)
                if task['id'] in taskIds and list(taskPlan['tasks']).count(task['id']) > 1:
                    logger.error(f"Task {i} has duplicate ID: {task['id']}")
                    return False
                
                dependencies = task.get('dependencies', [])
                if not isinstance(dependencies, list):
                    logger.error(f"Task {i} dependencies is not a list: {type(dependencies)}")
                    return False
                    
                for dep in dependencies:
                    if dep not in taskIds and dep != 'task_0':
                        logger.error(f"Task {i} has invalid dependency: {dep} (available: {list(taskIds) + ['task_0']})")
                        return False
                        
            logger.info(f"Task plan validation successful with {len(taskIds)} tasks")
            return True
            
        except Exception as e:
            logger.error(f"Error validating task plan: {str(e)}")
            return False
    
    def validateAction(self, actions: List[Dict[str, Any]], context) -> bool:
        """Validate action structure"""
        try:
            if not isinstance(actions, list):
                logger.error("Actions must be a list")
                return False
            if len(actions) == 0:
                logger.warning("No actions generated")
                return False
            for i, action in enumerate(actions):
                if not isinstance(action, dict):
                    logger.error(f"Action {i} must be a dictionary")
                    return False
                # Check for compound action format (new) or separate method/action format (old)
                if 'action' in action and '.' in str(action.get('action', '')):
                    # New compound action format: "method.action"
                    requiredFields = ['action', 'parameters', 'resultLabel']
                else:
                    # Old separate format: method + action fields
                    requiredFields = ['method', 'action', 'parameters', 'resultLabel']
                
                missingFields = []
                for field in requiredFields:
                    if field not in action or not action[field]:
                        missingFields.append(field)
                if missingFields:
                    logger.error(f"Action {i} missing required fields: {missingFields}")
                    return False
                resultLabel = action.get('resultLabel', '')
                if not resultLabel.startswith('round'):
                    logger.error(f"Action {i} result label must start with 'round': {resultLabel}")
                    return False
                parameters = action.get('parameters', {})
                if not isinstance(parameters, dict):
                    logger.error(f"Action {i} parameters must be a dictionary")
                    return False
            logger.info(f"Successfully validated {len(actions)} actions")
            return True
        except Exception as e:
            logger.error(f"Error validating actions: {str(e)}")
            return False
