#!/usr/bin/env python3
# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""
Anti-Pattern Builder: Convert DON'T_WANTS into anti-patterns (V43.13)

Flow: DON'T_WANTS evidence -> Check threshold (>=2 similar) -> Build anti-pattern
      -> Store in active registry -> Update ANTI_PATTERNS.md -> Alert agents
"""

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.parent
if str(ROOT_DIR) not in sys.path:
    sys.path.insert(0, str(ROOT_DIR))

from pulse.core.brain_utils import (
    EVIDENCE_DIR,
    GROWTH_METRICS,
    HIPPOCAMPUS_DIR,
    load_config,
    load_json,
    load_json_dict,
    save_json,
)
from pulse.admin.patterns.anti_pattern_similarity import (
    check_against_anti_patterns,
    cluster_dont_wants,
)

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

DONT_WANTS_FILE = EVIDENCE_DIR / "Intents" / "dont_wants.json"
ACTIVE_ANTI_PATTERNS = EVIDENCE_DIR / "Anti_Patterns" / "anti_patterns_active.json"
ANTI_PATTERNS_MD = ROOT_DIR / "Hippocampus" / "Patterns" / "anti_patterns.md"

MIN_DONT_WANTS = 2

def build_anti_patterns() -> dict:
    """
    Scan DON'T_WANTS evidence, find clusters, build anti-patterns.

    Returns dict with new anti-patterns created and stats.
    """
    dont_wants = load_json(DONT_WANTS_FILE)
    existing = load_json(ACTIVE_ANTI_PATTERNS)
    existing_descriptions = {ap.get("description", "").lower() for ap in existing}

    results = {
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "dont_wants_scanned": len(dont_wants),
        "clusters_found": 0,
        "new_anti_patterns": 0,
        "anti_patterns": [],
    }

    if len(dont_wants) < MIN_DONT_WANTS:
        log.info("Not enough DON'T_WANTS (%d < %d)", len(dont_wants), MIN_DONT_WANTS)
        return results

    clusters = cluster_dont_wants(dont_wants)
    results["clusters_found"] = len(clusters)

    for cluster in clusters:
        if len(cluster) < MIN_DONT_WANTS:
            continue

        anti_pattern = _synthesize_anti_pattern(cluster)

        if anti_pattern["description"].lower() in existing_descriptions:
            continue

        existing.append(anti_pattern)
        results["new_anti_patterns"] += 1
        results["anti_patterns"].append(anti_pattern["description"])
        log.info("New anti-pattern: %s (from %d DON'T_WANTS)",
                 anti_pattern["description"], len(cluster))

    if results["new_anti_patterns"] > 0:
        save_json(ACTIVE_ANTI_PATTERNS, existing)
        _update_growth_metrics(results)
        log.info("Total active anti-patterns: %d", len(existing))

    return results

def _synthesize_anti_pattern(cluster: list) -> dict:
    """Synthesize a cluster of DON'T_WANTS into a formal anti-pattern."""
    now = datetime.now(timezone.utc).isoformat()

    descriptions = [dw.get("dont_want", "") for dw in cluster]
    reasons = [dw.get("reason", "") for dw in cluster]
    domains = [dw.get("domain", "general") for dw in cluster]

    domain_counts = {}
    for d in domains:
        domain_counts[d] = domain_counts.get(d, 0) + 1
    primary_domain = max(domain_counts, key=domain_counts.get)

    all_words = []
    for desc in descriptions:
        all_words.extend(desc.lower().split())
    word_counts = {}
    for w in all_words:
        if len(w) > 3:
            word_counts[w] = word_counts.get(w, 0) + 1
    keywords = [w for w, c in sorted(word_counts.items(),
                key=lambda x: -x[1]) if c >= 2][:5]

    description = max(descriptions, key=len) if descriptions else "unknown"

    return {
        "id": f"AP-{now[:10].replace('-', '')}-{len(descriptions):03d}",
        "description": description,
        "reason": reasons[0] if reasons else "accumulated user rejections",
        "evidence_count": len(cluster),
        "domain": primary_domain,
        "keywords": keywords,
        "severity": "high" if len(cluster) >= 4 else "medium",
        "status": "active",
        "created": now,
        "source_dont_wants": len(cluster),
        "rule": f"NEVER: {description}",
    }

def _update_growth_metrics(results: dict):
    """Update growth metrics with anti-pattern build stats."""
    metrics = load_json_dict(GROWTH_METRICS)
    ap_metrics = metrics.get("anti_pattern_builder", {
        "total_scans": 0,
        "total_anti_patterns_created": 0,
        "last_scan": None,
    })
    ap_metrics["total_scans"] = ap_metrics.get("total_scans", 0) + 1
    ap_metrics["total_anti_patterns_created"] = (
        ap_metrics.get("total_anti_patterns_created", 0)
        + results["new_anti_patterns"]
    )
    ap_metrics["last_scan"] = results["timestamp"]
    metrics["anti_pattern_builder"] = ap_metrics
    save_json(GROWTH_METRICS, metrics)

def promote_repeated_failures(min_occurrences=3) -> dict:
    """Promote repeated failures (3+ identical) to anti-patterns automatically."""
    fails_file = HIPPOCAMPUS_DIR / "Failures" / "auto_fails.md"
    if not fails_file.exists():
        return {"promoted": 0, "reason": "no failures file"}

    content = fails_file.read_text(encoding="utf-8", errors="ignore")
    existing = load_json(ACTIVE_ANTI_PATTERNS)
    existing_descriptions = {ap.get("description", "").lower() for ap in existing}

    fail_counts = {}
    for line in content.splitlines():
        line = line.strip()
        if line.startswith("- ") and len(line) > 15:
            desc = line[2:].strip()
            import re
            desc_clean = re.sub(r"\[.*?\]", "", desc).strip().lower()
            if len(desc_clean) > 10:
                fail_counts[desc_clean] = fail_counts.get(desc_clean, 0) + 1

    promoted = 0
    now = datetime.now(timezone.utc).isoformat()
    for desc, count in fail_counts.items():
        if count < min_occurrences:
            continue
        if desc in existing_descriptions:
            continue
        anti_pattern = {
            "id": f"AP-FAIL-{now[:10].replace('-', '')}-{promoted:03d}",
            "description": desc,
            "reason": f"repeated failure ({count} occurrences)",
            "evidence_count": count,
            "domain": "general",
            "keywords": [w for w in desc.split() if len(w) > 4][:5],
            "severity": "high" if count >= 5 else "medium",
            "status": "active",
            "created": now,
            "source_dont_wants": 0,
            "source_failures": count,
            "rule": f"NEVER: {desc}",
        }
        existing.append(anti_pattern)
        existing_descriptions.add(desc)
        promoted += 1
        log.info("Failure->anti-pattern: %s (%dx)", desc[:60], count)

    if promoted > 0:
        save_json(ACTIVE_ANTI_PATTERNS, existing)

    return {"promoted": promoted, "failures_scanned": len(fail_counts)}

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--check":
        # Check a proposed action against anti-patterns
        if len(sys.argv) < 3:
            print("Usage: python anti_pattern_builder.py --check <proposed_action>")
            sys.exit(1)
        matches = check_against_anti_patterns(sys.argv[2])
        print(json.dumps(matches, indent=2))
    else:
        # Build anti-patterns from accumulated DON'T_WANTS
        result = build_anti_patterns()
        print(json.dumps(result, indent=2))
