"""
Type Hints and TypedDict Definitions for Storm Logger MCP Server

This module provides comprehensive type definitions for AI-agent-friendly code:
- TypedDict for complex data structures
- Protocol classes for interfaces
- Generic type variables
- Custom type aliases for clarity
"""

from typing import (
    Dict, List, Optional, Union, Literal, Any, TypedDict, 
    Protocol, TypeVar, Generic, Callable, Tuple, Set
)
from pathlib import Path
from datetime import datetime
from dataclasses import dataclass

try:
    from .constants import (
        TestMarker, RevenueImpact, ComplianceFramework, 
        SecurityLevel, CoverageThreshold
    )
except ImportError:
    # Fallback for different import contexts
    try:
        from constants import (
            TestMarker, RevenueImpact, ComplianceFramework, 
            SecurityLevel, CoverageThreshold
        )
    except ImportError:
        # Define minimal fallbacks
        from enum import Enum
        
        class TestMarker(Enum):
            UNIT = "unit"
            INTEGRATION = "integration"
            FUNCTIONAL = "functional"
            PERFORMANCE = "performance"
            
        class RevenueImpact(Enum):
            CRITICAL = "critical"
            HIGH = "high"
            MEDIUM = "medium"
            LOW = "low"
            
        class ComplianceFramework(Enum):
            GDPR = "gdpr"
            HIPAA = "hipaa"
            SOC2 = "soc2"
            
        class SecurityLevel(Enum):
            BASIC = "basic"
            STANDARD = "standard"
            ENHANCED = "enhanced"
            
        class CoverageThreshold(Enum):
            GOOD = 90.0


# ============================================================================
# Generic Type Variables
# ============================================================================

T = TypeVar('T')
ConfigT = TypeVar('ConfigT', bound='BaseConfig')
ResponseT = TypeVar('ResponseT', bound='MCPResponse')


# ============================================================================
# Coverage Analysis Types
# ============================================================================

class CoverageData(TypedDict):
    """Structured coverage data for AI agents to parse."""
    overall_coverage: float
    modules: List['ModuleCoverageData']
    total_lines: int
    covered_lines: int
    missing_lines: int
    branch_coverage: Optional[float]
    complexity_average: Optional[float]


class ModuleCoverageData(TypedDict):
    """Coverage data for a single module."""
    path: str
    name: str
    coverage_percent: float
    covered_lines: int
    total_lines: int
    missing_lines: List[int]
    missing_branches: Optional[List[Tuple[int, str]]]
    complexity: Optional[int]
    business_critical: bool
    revenue_impact: RevenueImpact


class CoverageGap(TypedDict):
    """Detailed information about a coverage gap."""
    module: str
    function: str
    lines: List[int]
    priority: int
    business_impact: str
    suggested_test_type: TestMarker
    estimated_effort_hours: float
    example_test: str


class CoverageReport(TypedDict):
    """Complete coverage report structure."""
    summary: CoverageData
    gaps: List[CoverageGap]
    trends: 'CoverageTrend'
    recommendations: List[str]
    business_metrics: 'BusinessMetricsData'


class CoverageTrend(TypedDict):
    """Coverage trend analysis data."""
    current: float
    previous: float
    change: float
    velocity: float  # Percentage points per day
    eta_to_target: Optional[int]  # Days to reach target
    historical: List['CoverageSnapshot']


class CoverageSnapshot(TypedDict):
    """Point-in-time coverage snapshot."""
    timestamp: str  # ISO format
    coverage: float
    modules_count: int
    commit: Optional[str]


# ============================================================================
# Test Generation Types
# ============================================================================

class TestTemplate(TypedDict):
    """Template for generated tests."""
    imports: List[str]
    fixtures: List['FixtureDefinition']
    test_class: Optional[str]
    test_methods: List['TestMethodDefinition']
    markers: List[TestMarker]
    docstring: str


class FixtureDefinition(TypedDict):
    """Pytest fixture definition."""
    name: str
    scope: Literal["function", "class", "module", "session"]
    code: str
    docstring: str
    dependencies: List[str]


class TestMethodDefinition(TypedDict):
    """Test method definition."""
    name: str
    docstring: str
    markers: List[str]
    parameters: Optional[List['ParameterSet']]
    body: str
    assertions: List[str]


class ParameterSet(TypedDict):
    """Parametrized test parameter set."""
    id: str
    values: Dict[str, Any]
    marks: Optional[List[str]]


# ============================================================================
# Business Intelligence Types
# ============================================================================

class BusinessMetricsData(TypedDict):
    """Business metrics for Storm Logger intelligence."""
    revenue_at_risk: float
    enterprise_readiness_score: float
    compliance_gaps: List['ComplianceGap']
    performance_impact: 'PerformanceMetrics'
    critical_modules: List['CriticalModuleInfo']


class ComplianceGap(TypedDict):
    """Compliance framework gap."""
    framework: ComplianceFramework
    requirement: str
    current_state: str
    required_state: str
    remediation_steps: List[str]
    priority: RevenueImpact


class PerformanceMetrics(TypedDict):
    """Performance metrics for 6M logs/sec target."""
    current_throughput: int
    target_throughput: int
    bottlenecks: List['PerformanceBottleneck']
    optimization_suggestions: List[str]


class PerformanceBottleneck(TypedDict):
    """Performance bottleneck identification."""
    component: str
    impact_percent: float
    description: str
    solution: str
    estimated_improvement: float


class CriticalModuleInfo(TypedDict):
    """Information about business-critical modules."""
    module: str
    revenue_impact: float
    usage_frequency: float
    dependencies: List[str]
    coverage: float
    risk_score: float


# ============================================================================
# Security Analysis Types
# ============================================================================

class SecurityFinding(TypedDict):
    """Security vulnerability finding."""
    id: str
    severity: SecurityLevel
    type: str
    location: 'CodeLocation'
    description: str
    remediation: str
    cwe_id: Optional[str]
    owasp_category: Optional[str]


class CodeLocation(TypedDict):
    """Precise code location."""
    file: str
    line: int
    column: Optional[int]
    function: Optional[str]
    snippet: str


class SecurityReport(TypedDict):
    """Complete security analysis report."""
    scan_date: str
    total_issues: int
    critical_issues: int
    findings: List[SecurityFinding]
    compliance_status: Dict[ComplianceFramework, bool]
    recommendations: List[str]


# ============================================================================
# Pattern Matching Types (Escape Regex Hell)
# ============================================================================

class PatternDefinition(TypedDict):
    """Pattern definition for sanitization."""
    name: str
    pattern: str
    replacement: str
    priority: int
    description: str
    examples: List['PatternExample']
    performance_note: Optional[str]


class PatternExample(TypedDict):
    """Example of pattern matching."""
    input: str
    output: str
    explanation: str


class PatternMatchResult(TypedDict):
    """Result of pattern matching operation."""
    original: str
    sanitized: str
    matches_found: int
    patterns_applied: List[str]
    performance_ms: float


# ============================================================================
# GitLab CI/CD Types
# ============================================================================

class GitLabPipelineConfig(TypedDict):
    """GitLab pipeline configuration."""
    stages: List[str]
    variables: Dict[str, str]
    jobs: Dict[str, 'GitLabJob']
    includes: List[str]
    rules: List['PipelineRule']


class GitLabJob(TypedDict):
    """GitLab CI job definition."""
    stage: str
    script: List[str]
    before_script: Optional[List[str]]
    after_script: Optional[List[str]]
    artifacts: Optional['ArtifactsConfig']
    cache: Optional['CacheConfig']
    rules: Optional[List['JobRule']]
    needs: Optional[List[str]]
    tags: Optional[List[str]]


class ArtifactsConfig(TypedDict):
    """GitLab artifacts configuration."""
    paths: List[str]
    expire_in: str
    reports: Optional[Dict[str, str]]


class CacheConfig(TypedDict):
    """GitLab cache configuration."""
    key: str
    paths: List[str]
    policy: Literal["pull", "push", "pull-push"]


class PipelineRule(TypedDict):
    """Pipeline execution rule."""
    if_condition: str
    when: Literal["always", "never", "on_success", "on_failure"]
    variables: Optional[Dict[str, str]]


class JobRule(TypedDict):
    """Job execution rule."""
    if_condition: Optional[str]
    changes: Optional[List[str]]
    when: Literal["always", "never", "on_success", "on_failure", "manual"]


# ============================================================================
# Configuration Types
# ============================================================================

@dataclass
class BaseConfig:
    """Base configuration class for all MCP tools."""
    debug: bool = False
    timeout: int = 300
    max_retries: int = 3
    
    def validate(self) -> None:
        """Validate configuration values."""
        if self.timeout <= 0:
            raise ValueError("Timeout must be positive")
        if self.max_retries < 0:
            raise ValueError("Max retries cannot be negative")


@dataclass
class CoverageConfig(BaseConfig):
    """Configuration for coverage analysis tools."""
    threshold: float = CoverageThreshold.GOOD.value
    include_branches: bool = True
    parallel: bool = True
    fail_under: Optional[float] = None
    
    def validate(self) -> None:
        """Validate coverage configuration."""
        super().validate()
        if not 0 <= self.threshold <= 100:
            raise ValueError("Coverage threshold must be between 0 and 100")


@dataclass
class TestGenerationConfig(BaseConfig):
    """Configuration for test generation tools."""
    strategy: Literal["minimal", "standard", "comprehensive", "enterprise"] = "standard"
    include_fixtures: bool = True
    include_edge_cases: bool = True
    include_performance_tests: bool = False
    markers: List[TestMarker] = None
    
    def __post_init__(self):
        if self.markers is None:
            self.markers = [TestMarker.UNIT]


@dataclass
class SecurityConfig(BaseConfig):
    """Configuration for security scanning tools."""
    level: SecurityLevel = SecurityLevel.STANDARD
    frameworks: List[ComplianceFramework] = None
    include_dependencies: bool = True
    fail_on_critical: bool = True
    
    def __post_init__(self):
        if self.frameworks is None:
            self.frameworks = [ComplianceFramework.GDPR, ComplianceFramework.SOC2]


# ============================================================================
# Protocol Definitions (Interfaces)
# ============================================================================

class Analyzer(Protocol):
    """Protocol for all analyzer implementations."""
    
    def analyze(self, target: Path) -> Dict[str, Any]:
        """Analyze the target and return results."""
        ...
    
    def get_metrics(self) -> Dict[str, float]:
        """Get analysis metrics."""
        ...


class Reporter(Protocol):
    """Protocol for all reporter implementations."""
    
    def generate_report(self, data: Dict[str, Any], format: str) -> str:
        """Generate a report in the specified format."""
        ...
    
    def export(self, report: str, path: Path) -> None:
        """Export the report to a file."""
        ...


class TestGenerator(Protocol):
    """Protocol for test generation implementations."""
    
    def generate_tests(self, module: str, config: TestGenerationConfig) -> TestTemplate:
        """Generate tests for the specified module."""
        ...
    
    def validate_tests(self, tests: str) -> List[str]:
        """Validate generated tests and return any issues."""
        ...


# ============================================================================
# Response Enhancement Types
# ============================================================================

class ToolExample(TypedDict):
    """Example usage of an MCP tool."""
    description: str
    command: str
    expected_output: str
    use_case: str


class NextStep(TypedDict):
    """Suggested next step after tool execution."""
    action: str
    tool: str
    reason: str
    priority: int


class ErrorContext(TypedDict):
    """Enhanced error context for debugging."""
    error_type: str
    error_message: str
    stack_trace: Optional[str]
    context: Dict[str, Any]
    suggestions: List[str]
    related_documentation: List[str]


# ============================================================================
# Type Aliases for Clarity
# ============================================================================

ModulePath = Union[str, Path]
CoveragePercent = float  # 0.0 to 100.0
LineNumber = int
CommitHash = str
Timestamp = Union[str, datetime]
FileContent = str
JSONString = str
RegexPattern = str
TestResult = Literal["passed", "failed", "skipped", "xfailed", "xpassed"]