# src/ctf/analysis.py
# {{{ imports
import re
from dataclasses import dataclass
from pathlib import Path
# }}}

# {{{ RouteResult
@dataclass
class RouteResult:
    route_name: str
    executed: bool
    success: bool
    message: str
    details: dict | None = None
    extracted_flags: list[str] | None = None
# }}}

# {{{ AnalysisResult
@dataclass
class AnalysisResult:
    success: bool
    routes: list[RouteResult]
# }}}

# {{{ run_metadata_route
def run_metadata_route(file_path: Path) -> RouteResult:
    """Extracts file metadata and scans for potential flags or hints."""
    from ctf.forensics import get_metadata
    from ctf.decoding import check_for_flag
    
    file_path = Path(file_path).resolve()
    if not file_path.exists():
        return RouteResult(
            route_name="File Metadata Extraction",
            executed=True,
            success=False,
            message=f"File not found: {file_path}"
        )
        
    try:
        meta = get_metadata(file_path)
        extracted_flags = []
        
        # Scan comment, EXIF attributes, and decoded hints
        if meta.comment:
            extracted_flags.extend(check_for_flag(meta.comment))
            
        for val in meta.exif_data.values():
            if isinstance(val, str):
                extracted_flags.extend(check_for_flag(val))
                
        for dec_dict in meta.decoded_hints.values():
            for dec_val in dec_dict.values():
                extracted_flags.extend(check_for_flag(dec_val))
                
        extracted_flags = list(set(extracted_flags))
        success = True
        
        if extracted_flags:
            msg = f"Metadata inspected. Found {len(extracted_flags)} potential flag(s)."
        else:
            msg = "Metadata inspected. No obvious flags or decoded hints found."
            
        details = {
            "Filename": meta.filename,
            "Size": f"{meta.size} bytes",
            "Detected Type": meta.detected_type,
            "Magic": meta.magic,
            "Has EXIF": "Yes" if meta.exif_data else "No",
            "Has Comment": "Yes" if meta.comment else "No",
            "Has Hints": "Yes" if meta.decoded_hints else "No",
        }
        
        return RouteResult(
            route_name="File Metadata Extraction",
            executed=True,
            success=success,
            message=msg,
            details=details,
            extracted_flags=extracted_flags
        )
    except Exception as e:
        return RouteResult(
            route_name="File Metadata Extraction",
            executed=True,
            success=False,
            message=f"Error extracting metadata: {str(e)}"
        )
# }}}

# {{{ run_analysis
def run_analysis(file_path: Path | None = None) -> AnalysisResult:
    """Executes all registered analysis routes to analyze and solve a challenge."""
    routes = []
    
    # Route 1: Metadata Extraction
    if file_path:
        routes.append(run_metadata_route(Path(file_path)))
    else:
        routes.append(RouteResult(
            route_name="File Metadata Extraction",
            executed=False,
            success=False,
            message="No file attached to analyze."
        ))
        
    success = any(r.success and r.extracted_flags for r in routes)
    return AnalysisResult(success=success, routes=routes)
# }}}
