# src/ctf/steg.py
# {{{ imports
import shutil
import subprocess
import tempfile
from dataclasses import dataclass
from pathlib import Path
# }}}

# {{{ SteghideCrackResult
@dataclass
class SteghideCrackResult:
    success: bool
    password: str | None = None
    payload: bytes | None = None
    error_message: str | None = None
# }}}

# {{{ crack_steghide
def crack_steghide(file_path: Path, wordlist: list[str]) -> SteghideCrackResult:
    """Tries to extract data from a file using steghide with a wordlist."""
    if not shutil.which("steghide"):
        return SteghideCrackResult(success=False, error_message="steghide executable not found on system PATH.")
        
    file_path = Path(file_path).resolve()
    if not file_path.exists():
        return SteghideCrackResult(success=False, error_message=f"File not found: {file_path}")
        
    for password in wordlist:
        password = password.strip()
        with tempfile.TemporaryDirectory() as tmpdir:
            out_file = Path(tmpdir) / "extracted_payload"
            cmd = ["steghide", "extract", "-sf", str(file_path), "-p", password, "-xf", str(out_file), "-f"]
            try:
                # Capture standard outputs; timeout to prevent indefinite hangs
                result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5)
                if result.returncode == 0 and out_file.exists():
                    return SteghideCrackResult(
                        success=True,
                        password=password,
                        payload=out_file.read_bytes()
                    )
            except subprocess.TimeoutExpired:
                pass
            except Exception as e:
                return SteghideCrackResult(success=False, error_message=str(e))
                
    return SteghideCrackResult(success=False, error_message="Password not found in wordlist.")
# }}}
