"""
spidercrypt.audit
~~~~~~~~~~~~~~~~~
Static secret scanning for source files.
"""

import re
from pathlib import Path
from typing import List, Dict, Any

from .patterns import SECRET_PATTERNS, RISKY_CODE_PATTERNS


def scan_secrets(text: str) -> List[str]:
    """
    Scan *text* for known secret patterns.

    Returns:
        List of matched pattern strings (may be empty).
    """
    return [p for p in SECRET_PATTERNS if re.search(p, text)]


def scan_risky_code(text: str) -> List[str]:
    """
    Scan *text* for risky code constructs (eval, exec, pickle, …).

    Returns:
        List of matched pattern strings (may be empty).
    """
    return [p for p in RISKY_CODE_PATTERNS if p in text]


def audit_file(filepath: str, ai: bool = False) -> Dict[str, Any]:
    """
    Run a full static audit on *filepath*.

    Args:
        filepath: Path to the source file to analyse.
        ai:       If ``True`` and LangChain/Ollama are available,
                  an AI-assisted pass is performed after the regex scan.

    Returns:
        A dict with keys ``secrets_found``, ``secret_patterns``,
        ``risky_code``, and optionally ``ai_analysis``.
    """
    code = Path(filepath).read_text(encoding="utf-8", errors="replace")

    secrets  = scan_secrets(code)
    risky    = scan_risky_code(code)

    report: Dict[str, Any] = {
        "file":            filepath,
        "secrets_found":   len(secrets),
        "secret_patterns": secrets,
        "risky_code":      risky,
    }

    if ai:
        try:
            from langchain_ollama import OllamaLLM
            from langchain_core.prompts import ChatPromptTemplate
            from langchain_core.output_parsers import StrOutputParser

            prompt = ChatPromptTemplate.from_messages([
                ("system", "You are a security expert. Analyse the following code for vulnerabilities."),
                ("human", "{code}"),
            ])
            chain = prompt | OllamaLLM(model="llama3") | StrOutputParser()
            report["ai_analysis"] = chain.invoke({"code": code[:4000]})
        except ImportError:
            report["ai_analysis"] = "langchain-ollama not installed."

    return report