#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
Auto-Capture Daemon: Real-time evidence capture from terminal interactions (V43.14)

Core capture loop, thresholds, and CLI entry point.
Routing helpers and batch modes live in capture_routing.py (Law 7 split).

Flow:
  Input (prompt + response) -> Parse (WANTS/DON'T_WANTS) -> Route (evidence buckets)
  -> Check thresholds -> Trigger synthesis if needed -> Update growth metrics

Dependencies: capture_routing, brain_utils, wants_parser (Python stdlib only via Law 4)
"""

import json
import logging
import sys
from datetime import datetime, timezone
from pathlib import Path

SCRIPT_DIR = Path(__file__).resolve().parent
ROOT_DIR = SCRIPT_DIR.parent.parent
if str(ROOT_DIR) not in sys.path:
    sys.path.insert(0, str(ROOT_DIR))

from pulse.core.brain_utils import (
    EVIDENCE_DIR,
    WANTS_FILE,
    load_config,
    load_json,
    save_json,
)
from pulse.brain.wants_parser import parse_full
from pulse.core.pii_filter import redact_pii

# Import routing helpers — re-exported for backward compat
from pulse.brain.capture_routing import (
    WANTS_EVIDENCE,
    DONT_WANTS_EVIDENCE,
    SESSION_EVIDENCE,
    ANTI_PATTERNS_ACTIVE,
    is_business_content as _is_business_content,
    count_similar_wants as _count_similar_wants,
    count_similar_dont_wants as _count_similar_dont_wants,
    route_to_domain as _route_to_domain,
    update_growth_metrics as _update_growth_metrics,
    batch_capture as _batch_capture_impl,
    batch_capture_from_log as _batch_capture_from_log_impl,
)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [AUTO_CAPTURE] %(message)s",
    datefmt="%H:%M:%S",
)
log = logging.getLogger("auto_capture")


def capture(user_prompt: str, agent_response: str = "",
            session_id: str = "") -> dict:
    """
    Main capture function: parse input and route to evidence buckets.

    Args:
        user_prompt: The user's input text
        agent_response: The agent's response text (may be empty)
        session_id: Optional session identifier

    Returns:
        dict with capture results (items stored, thresholds hit, etc.)
    """
    if not user_prompt or len(user_prompt.strip()) < 3:
        return {"status": "skipped", "reason": "prompt too short"}

    # Filter business/non-technical content
    if _is_business_content(user_prompt):
        return {"status": "skipped", "reason": "business content filtered"}

    now = datetime.now(timezone.utc).isoformat()
    config = load_config()

    # Parse WANTS and DON'T_WANTS
    parsed = parse_full(user_prompt, agent_response)

    results = {
        "timestamp": now,
        "wants_stored": 0,
        "dont_wants_stored": 0,
        "session_items": 0,
        "thresholds_hit": [],
        "synthesis_triggered": False,
    }

    # 1. Store WANTS
    if parsed["wants"]:
        wants = load_json(WANTS_EVIDENCE)
        for want in parsed["wants"]:
            want["session_id"] = session_id
            wants.append(want)
        save_json(WANTS_EVIDENCE, wants)
        results["wants_stored"] = len(parsed["wants"])
        log.info("Stored %d WANTS", len(parsed["wants"]))

        # Check benchmark threshold
        threshold = config.get("synthesis", {}).get("default_threshold", 5)
        similar = _count_similar_wants(wants, parsed["wants"][-1]["want"])
        if similar >= 3:
            results["thresholds_hit"].append("wants_benchmark")
            log.info("WANTS benchmark threshold hit: %d similar", similar)

    # 2. Store DON'T_WANTS
    if parsed["dont_wants"]:
        dont_wants = load_json(DONT_WANTS_EVIDENCE)
        for dw in parsed["dont_wants"]:
            dw["session_id"] = session_id
            dw["evidence_count"] = 1
            dw["status"] = "active"
            dont_wants.append(dw)
        save_json(DONT_WANTS_EVIDENCE, dont_wants)
        results["dont_wants_stored"] = len(parsed["dont_wants"])
        log.info("Stored %d DON'T_WANTS", len(parsed["dont_wants"]))

        # Check anti-pattern threshold
        similar_dw = _count_similar_dont_wants(
            dont_wants, parsed["dont_wants"][-1].get("dont_want", "")
        )
        if similar_dw >= 2:
            results["thresholds_hit"].append("anti_pattern_build")
            log.info("Anti-pattern threshold hit: %d similar", similar_dw)

            # Route repeated dont_wants to user profile
            try:
                from pulse.core.user_profile import UserProfile
                profile = UserProfile.load()
                for dw in parsed["dont_wants"]:
                    text = dw.get("dont_want", "")[:100]
                    if text and text not in profile.dont_wants:
                        profile.dont_wants.append(text)
                profile.dont_wants = profile.dont_wants[-20:]  # cap at 20
                profile.save()
                log.info("Updated user profile with %d dont_wants", len(parsed["dont_wants"]))
            except Exception:
                pass

    # 3. Store session evidence (every interaction)
    prompt_summary = user_prompt[:200].strip() if user_prompt else ""
    response_summary = agent_response[:200].strip() if agent_response else ""
    description = redact_pii(prompt_summary or response_summary or "[no content]")
    session_item = {
        "type": "OBSERVATION",
        "source": "auto_capture",
        "timestamp": now,
        "session_id": session_id,
        "domain": parsed["primary_domain"],
        "priority": parsed["priority"],
        "description": description,
        "has_wants": len(parsed["wants"]) > 0,
        "has_dont_wants": len(parsed["dont_wants"]) > 0,
        "has_rejection": parsed["has_rejection"],
        "prompt_length": len(user_prompt),
        "response_length": len(agent_response),
    }
    session_data = load_json(SESSION_EVIDENCE)
    session_data.append(session_item)
    save_json(SESSION_EVIDENCE, session_data)
    results["session_items"] = 1

    # 4. Route to domain evidence
    domain = parsed["primary_domain"]
    if domain != "general":
        _route_to_domain(domain, user_prompt, agent_response, now, session_id)

    # 5. Check synthesis threshold
    synthesis_threshold = config.get("synthesis", {}).get("default_threshold", 5)
    domain_threshold = config.get("synthesis", {}).get(
        "domain_thresholds", {}
    ).get(domain, synthesis_threshold)

    domain_evidence_file = EVIDENCE_DIR / f"{domain}_learnings.json"
    if domain_evidence_file.exists():
        domain_count = len(load_json(domain_evidence_file))
        if domain_count >= domain_threshold:
            results["synthesis_triggered"] = True
            log.info("Synthesis threshold reached for %s (%d items)",
                     domain, domain_count)

    # 6. Update growth metrics
    _update_growth_metrics(results)

    return results


def batch_capture() -> dict:
    """Batch mode wrapper — delegates to capture_routing with capture() injected."""
    return _batch_capture_impl(capture)


def batch_capture_from_log(log_path: str) -> dict:
    """Log batch mode wrapper — delegates to capture_routing with capture() injected."""
    return _batch_capture_from_log_impl(log_path, capture)


# === CLI ===

if __name__ == "__main__":
    if "--log-file" in sys.argv:
        idx = sys.argv.index("--log-file")
        if idx + 1 < len(sys.argv):
            result = batch_capture_from_log(sys.argv[idx + 1])
            print(json.dumps(result, indent=2))
        else:
            print("Error: --log-file requires a path argument")
            sys.exit(1)
    elif len(sys.argv) > 1 and sys.argv[1] == "--batch":
        result = batch_capture()
        print(json.dumps(result, indent=2))
    elif len(sys.argv) < 2:
        print("Usage: python auto_capture.py <user_prompt> [agent_response] [session_id]")
        print("       python auto_capture.py --batch  (retroactive from session JSON)")
        print("       python auto_capture.py --log-file <path>  (retroactive from log file)")
        sys.exit(1)
    else:
        prompt = sys.argv[1]
        response = sys.argv[2] if len(sys.argv) > 2 else ""
        sid = sys.argv[3] if len(sys.argv) > 3 else ""

        result = capture(prompt, response, sid)
        print(json.dumps(result, indent=2))
