from typing import Any, Dict, List, Optional, Tuple
import json
import regex as re
from .validators import (
    detect_placeholder_tokens,
    detect_synthetic_markers,
    detect_inferred_virtual_signals,
)
from .sources.registry import CrossChecker
from .audit.schema import AuditEntry, AuditReport

def normalize_payload(payload: str) -> Tuple[str, Optional[Dict[str, Any]]]:
    is_json = False
    obj: Optional[Dict[str, Any]] = None
    s = payload.strip()
    try:
        obj = json.loads(s)
        is_json = True
    except Exception:
        pass
    return ("json" if is_json else "text", obj if is_json else None)

def scan_text_rules(text: str, rules: Dict[str, Any]) -> List[str]:
    hits: List[str] = []
    for pat in rules.get("forbidden_regex", []):
        if re.search(pat, text, flags=re.I | re.M):
            hits.append(f"hit:{pat}")
    return hits

def evaluate(payload: str, rules: Dict[str, Any], checker: CrossChecker) -> AuditReport:
    kind, obj = normalize_payload(payload)
    entries: List[AuditEntry] = []

    placeholders = detect_placeholder_tokens(payload, rules)
    if placeholders:
        entries.append(AuditEntry(rule="placeholder", detail=str(placeholders), severity="high"))

    synthetic = detect_synthetic_markers(payload, rules)
    if synthetic:
        entries.append(AuditEntry(rule="synthetic", detail=str(synthetic), severity="high"))

    inferred = detect_inferred_virtual_signals(payload, rules)
    if inferred:
        entries.append(AuditEntry(rule="inferred_or_virtual", detail=str(inferred), severity="high"))

    text_to_scan = payload if kind == "text" else json.dumps(obj, ensure_ascii=False)
    regex_hits = scan_text_rules(text_to_scan, rules)
    for h in regex_hits:
        entries.append(AuditEntry(rule="regex_forbidden", detail=h, severity="medium"))

    # 强制 2+ 权威源校对
    if rules.get("require_two_authorities", True):
        cc = checker.crosscheck(obj if obj is not None else {"text": payload})
        for e in cc.entries:
            entries.append(e)

    ok = all(e.severity != "high" for e in entries) and checker.ok
    return AuditReport(ok=ok, entries=entries)







# 说明文字用的 #：最小可用的 FilterPipeline（供 CLI 或外部调用装配）
class FilterPipeline:
    def __init__(self, checker=None, rules=None):
        self.checker = checker
        self.rules = rules

    def run(self, payload):
        # 说明文字用的 #：这里按你项目的真实逻辑替换；占位实现只返回结构
        return {"ok": True, "summary": "pipeline stub executed", "details": {}}

