"""
Unified Result Structures

Standardized data structures for workspace validation results that work
identically for single and multi-workspace scenarios.

Architecture:
- Unified result structures for all validation scenarios
- Consistent data models regardless of workspace count
- Standardized summary and reporting structures
- Backward compatibility with existing result formats

Features:
- Single validation result structure for count=1 or count=N
- Consistent summary statistics and reporting
- Standardized error handling and diagnostics
- Extensible result structure for future enhancements
"""

from datetime import datetime
from typing import Dict, List, Any, Optional, Union
from pydantic import BaseModel, Field, ConfigDict
import logging

logger = logging.getLogger(__name__)


class ValidationSummary(BaseModel):
    """
    Unified summary that works for count=1 or count=N workspaces.
    
    This summary structure provides consistent statistics regardless
    of whether validating a single workspace or multiple workspaces.
    """
    model_config = ConfigDict(
        extra='forbid',
        validate_assignment=True
    )
    
    total_workspaces: int = Field(
        description="Total number of workspaces validated"
    )
    successful_workspaces: int = Field(
        description="Number of workspaces that passed validation"
    )
    failed_workspaces: int = Field(
        description="Number of workspaces that failed validation"
    )
    success_rate: float = Field(
        description="Success rate as decimal (0.0 to 1.0)",
        ge=0.0,
        le=1.0
    )
    
    def __post_init__(self):
        """Validate summary consistency."""
        if self.total_workspaces != self.successful_workspaces + self.failed_workspaces:
            logger.warning("Inconsistent workspace counts in validation summary")
    
    @property
    def success_percentage(self) -> float:
        """Get success rate as percentage (0-100)."""
        return self.success_rate * 100.0
    
    @property
    def all_successful(self) -> bool:
        """Check if all workspaces passed validation."""
        return self.failed_workspaces == 0 and self.total_workspaces > 0
    
    @property
    def any_failed(self) -> bool:
        """Check if any workspaces failed validation."""
        return self.failed_workspaces > 0


class WorkspaceValidationResult(BaseModel):
    """
    Validation result for a single workspace entry.
    
    This structure is used for both single workspace scenarios (count=1)
    and individual workspace results in multi-workspace scenarios.
    """
    model_config = ConfigDict(
        extra='forbid',
        validate_assignment=True
    )
    
    workspace_id: str = Field(
        description="Unique identifier for the workspace"
    )
    workspace_type: str = Field(
        description="Type of workspace (single, developer, shared)"
    )
    workspace_path: str = Field(
        description="File system path to the workspace"
    )
    
    # Validation results
    success: bool = Field(
        description="Overall validation success for this workspace"
    )
    validation_start_time: Optional[str] = Field(
        default=None,
        description="ISO timestamp when validation started"
    )
    validation_end_time: Optional[str] = Field(
        default=None,
        description="ISO timestamp when validation completed"
    )
    validation_duration_seconds: Optional[float] = Field(
        default=None,
        description="Duration of validation in seconds"
    )
    
    # Detailed results by validation type
    alignment_results: Optional[Dict[str, Any]] = Field(
        default=None,
        description="Results from alignment validation"
    )
    builder_results: Optional[Dict[str, Any]] = Field(
        default=None,
        description="Results from builder validation"
    )
    
    # Error information
    error: Optional[str] = Field(
        default=None,
        description="Error message if validation failed"
    )
    warnings: List[str] = Field(
        default_factory=list,
        description="Warning messages from validation"
    )
    
    # Workspace metadata
    developer_info: Optional[Dict[str, Any]] = Field(
        default=None,
        description="Information about the developer workspace"
    )
    
    @property
    def has_alignment_results(self) -> bool:
        """Check if alignment validation was performed."""
        return self.alignment_results is not None
    
    @property
    def has_builder_results(self) -> bool:
        """Check if builder validation was performed."""
        return self.builder_results is not None
    
    @property
    def validation_types_run(self) -> List[str]:
        """Get list of validation types that were executed."""
        types = []
        if self.has_alignment_results:
            types.append("alignment")
        if self.has_builder_results:
            types.append("builders")
        return types
    
    def get_validation_duration(self) -> Optional[float]:
        """Get validation duration, calculating if not set."""
        if self.validation_duration_seconds is not None:
            return self.validation_duration_seconds
        
        if self.validation_start_time and self.validation_end_time:
            try:
                start = datetime.fromisoformat(self.validation_start_time.replace('Z', '+00:00'))
                end = datetime.fromisoformat(self.validation_end_time.replace('Z', '+00:00'))
                return (end - start).total_seconds()
            except Exception:
                return None
        
        return None


class UnifiedValidationResult(BaseModel):
    """
    Standardized result structure for all validation scenarios.
    
    This structure works identically whether validating a single workspace
    (count=1) or multiple workspaces (count=N), eliminating the need for
    separate result handling logic.
    """
    model_config = ConfigDict(
        extra='forbid',
        validate_assignment=True
    )
    
    # Validation metadata
    workspace_root: str = Field(
        description="Root directory of the workspace(s)"
    )
    workspace_type: str = Field(
        description="Type of workspace structure (single or multi)"
    )
    validation_start_time: str = Field(
        description="ISO timestamp when validation started"
    )
    validation_end_time: Optional[str] = Field(
        default=None,
        description="ISO timestamp when validation completed"
    )
    validation_duration_seconds: Optional[float] = Field(
        default=None,
        description="Total validation duration in seconds"
    )
    
    # Workspace results
    workspaces: Dict[str, WorkspaceValidationResult] = Field(
        description="Validation results for each workspace"
    )
    
    # Summary statistics
    summary: ValidationSummary = Field(
        description="Summary statistics for all workspaces"
    )
    
    # Recommendations and insights
    recommendations: List[str] = Field(
        default_factory=list,
        description="Recommendations based on validation results"
    )
    
    # Global error information
    global_error: Optional[str] = Field(
        default=None,
        description="Global error that prevented validation"
    )
    
    @property
    def is_single_workspace(self) -> bool:
        """Check if this represents a single workspace validation."""
        return self.workspace_type == "single" or len(self.workspaces) == 1
    
    @property
    def is_multi_workspace(self) -> bool:
        """Check if this represents a multi-workspace validation."""
        return self.workspace_type == "multi" and len(self.workspaces) > 1
    
    @property
    def workspace_count(self) -> int:
        """Get the number of workspaces validated."""
        return len(self.workspaces)
    
    @property
    def workspace_ids(self) -> List[str]:
        """Get list of workspace identifiers."""
        return list(self.workspaces.keys())
    
    @property
    def overall_success(self) -> bool:
        """Check if all workspaces passed validation."""
        return self.summary.all_successful and self.global_error is None
    
    @property
    def has_failures(self) -> bool:
        """Check if any workspaces failed validation."""
        return self.summary.any_failed or self.global_error is not None
    
    def get_workspace_result(self, workspace_id: str) -> Optional[WorkspaceValidationResult]:
        """Get validation result for a specific workspace."""
        return self.workspaces.get(workspace_id)
    
    def get_failed_workspaces(self) -> List[str]:
        """Get list of workspace IDs that failed validation."""
        return [
            workspace_id for workspace_id, result in self.workspaces.items()
            if not result.success
        ]
    
    def get_successful_workspaces(self) -> List[str]:
        """Get list of workspace IDs that passed validation."""
        return [
            workspace_id for workspace_id, result in self.workspaces.items()
            if result.success
        ]
    
    def get_validation_duration(self) -> Optional[float]:
        """Get total validation duration, calculating if not set."""
        if self.validation_duration_seconds is not None:
            return self.validation_duration_seconds
        
        if self.validation_start_time and self.validation_end_time:
            try:
                start = datetime.fromisoformat(self.validation_start_time.replace('Z', '+00:00'))
                end = datetime.fromisoformat(self.validation_end_time.replace('Z', '+00:00'))
                return (end - start).total_seconds()
            except Exception:
                return None
        
        return None
    
    def add_recommendation(self, recommendation: str) -> None:
        """Add a recommendation to the results."""
        if recommendation not in self.recommendations:
            self.recommendations.append(recommendation)
    
    def add_workspace_result(
        self,
        workspace_id: str,
        result: WorkspaceValidationResult
    ) -> None:
        """Add or update a workspace validation result."""
        self.workspaces[workspace_id] = result
        self._update_summary()
    
    def _update_summary(self) -> None:
        """Update summary statistics based on current workspace results."""
        total_workspaces = len(self.workspaces)
        successful_workspaces = len(self.get_successful_workspaces())
        failed_workspaces = total_workspaces - successful_workspaces
        success_rate = successful_workspaces / total_workspaces if total_workspaces > 0 else 0.0
        
        self.summary = ValidationSummary(
            total_workspaces=total_workspaces,
            successful_workspaces=successful_workspaces,
            failed_workspaces=failed_workspaces,
            success_rate=success_rate
        )
    
    def finalize_validation(self, end_time: Optional[datetime] = None) -> None:
        """Finalize validation results with end time and duration."""
        if end_time is None:
            end_time = datetime.now()
        
        self.validation_end_time = end_time.isoformat()
        
        # Calculate duration
        try:
            start = datetime.fromisoformat(self.validation_start_time.replace('Z', '+00:00'))
            self.validation_duration_seconds = (end_time - start).total_seconds()
        except Exception:
            logger.warning("Failed to calculate validation duration")
        
        # Update summary to ensure consistency
        self._update_summary()


class ValidationResultBuilder:
    """
    Builder class for creating unified validation results.
    
    This builder simplifies the creation of validation results and ensures
    consistency across different validation scenarios.
    """
    
    def __init__(
        self,
        workspace_root: str,
        workspace_type: str,
        start_time: Optional[datetime] = None
    ):
        """
        Initialize validation result builder.
        
        Args:
            workspace_root: Root directory of workspace(s)
            workspace_type: Type of workspace structure (single or multi)
            start_time: Validation start time (defaults to now)
        """
        self.workspace_root = workspace_root
        self.workspace_type = workspace_type
        self.start_time = start_time or datetime.now()
        self.workspaces: Dict[str, WorkspaceValidationResult] = {}
        self.recommendations: List[str] = []
        self.global_error: Optional[str] = None
    
    def add_workspace_result(
        self,
        workspace_id: str,
        workspace_type: str,
        workspace_path: str,
        success: bool,
        alignment_results: Optional[Dict[str, Any]] = None,
        builder_results: Optional[Dict[str, Any]] = None,
        error: Optional[str] = None,
        warnings: Optional[List[str]] = None,
        developer_info: Optional[Dict[str, Any]] = None,
        validation_start_time: Optional[datetime] = None,
        validation_end_time: Optional[datetime] = None
    ) -> 'ValidationResultBuilder':
        """Add a workspace validation result."""
        
        # Calculate validation duration if times provided
        validation_duration = None
        if validation_start_time and validation_end_time:
            validation_duration = (validation_end_time - validation_start_time).total_seconds()
        
        workspace_result = WorkspaceValidationResult(
            workspace_id=workspace_id,
            workspace_type=workspace_type,
            workspace_path=workspace_path,
            success=success,
            validation_start_time=validation_start_time.isoformat() if validation_start_time else None,
            validation_end_time=validation_end_time.isoformat() if validation_end_time else None,
            validation_duration_seconds=validation_duration,
            alignment_results=alignment_results,
            builder_results=builder_results,
            error=error,
            warnings=warnings or [],
            developer_info=developer_info
        )
        
        self.workspaces[workspace_id] = workspace_result
        return self
    
    def add_recommendation(self, recommendation: str) -> 'ValidationResultBuilder':
        """Add a recommendation."""
        if recommendation not in self.recommendations:
            self.recommendations.append(recommendation)
        return self
    
    def set_global_error(self, error: str) -> 'ValidationResultBuilder':
        """Set a global error that prevented validation."""
        self.global_error = error
        return self
    
    def build(self, end_time: Optional[datetime] = None) -> UnifiedValidationResult:
        """Build the final validation result."""
        if end_time is None:
            end_time = datetime.now()
        
        # Calculate summary statistics
        total_workspaces = len(self.workspaces)
        successful_workspaces = sum(1 for result in self.workspaces.values() if result.success)
        failed_workspaces = total_workspaces - successful_workspaces
        success_rate = successful_workspaces / total_workspaces if total_workspaces > 0 else 0.0
        
        summary = ValidationSummary(
            total_workspaces=total_workspaces,
            successful_workspaces=successful_workspaces,
            failed_workspaces=failed_workspaces,
            success_rate=success_rate
        )
        
        # Calculate total duration
        validation_duration = (end_time - self.start_time).total_seconds()
        
        return UnifiedValidationResult(
            workspace_root=self.workspace_root,
            workspace_type=self.workspace_type,
            validation_start_time=self.start_time.isoformat(),
            validation_end_time=end_time.isoformat(),
            validation_duration_seconds=validation_duration,
            workspaces=self.workspaces,
            summary=summary,
            recommendations=self.recommendations,
            global_error=self.global_error
        )


def create_single_workspace_result(
    workspace_root: str,
    workspace_id: str = "default",
    workspace_type: str = "single",
    workspace_path: Optional[str] = None,
    success: bool = True,
    alignment_results: Optional[Dict[str, Any]] = None,
    builder_results: Optional[Dict[str, Any]] = None,
    error: Optional[str] = None,
    recommendations: Optional[List[str]] = None,
    start_time: Optional[datetime] = None,
    end_time: Optional[datetime] = None
) -> UnifiedValidationResult:
    """
    Convenience function to create a single workspace validation result.
    
    This function creates a UnifiedValidationResult for a single workspace,
    treating it as a multi-workspace scenario with count=1.
    """
    builder = ValidationResultBuilder(
        workspace_root=workspace_root,
        workspace_type=workspace_type,
        start_time=start_time
    )
    
    builder.add_workspace_result(
        workspace_id=workspace_id,
        workspace_type=workspace_type,
        workspace_path=workspace_path or workspace_root,
        success=success,
        alignment_results=alignment_results,
        builder_results=builder_results,
        error=error,
        validation_start_time=start_time,
        validation_end_time=end_time
    )
    
    if recommendations:
        for rec in recommendations:
            builder.add_recommendation(rec)
    
    return builder.build(end_time)


def create_empty_result(
    workspace_root: str,
    workspace_type: str = "unknown",
    error: str = "No workspaces found",
    start_time: Optional[datetime] = None
) -> UnifiedValidationResult:
    """
    Create an empty validation result for cases where no workspaces are found.
    """
    builder = ValidationResultBuilder(
        workspace_root=workspace_root,
        workspace_type=workspace_type,
        start_time=start_time
    )
    
    builder.set_global_error(error)
    builder.add_recommendation("Ensure workspace structure is properly configured")
    
    return builder.build()
