# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
"""Crew composer validation checks: agent weaknesses, tier alignment, provider limits, epistemic conflict."""
from __future__ import annotations
import logging
import pulse.core.brain_utils as _brain_utils
from pulse.daemons.synthesis.swarm.crew_helpers import _COMPLEXITY_TIER

log = logging.getLogger("pulse.crew_composer")

OLLAMA_FREE_LIMIT = 5


def _check_agent_weaknesses(crew, domains):
    """Check D2 agent profiles for domain weaknesses in current crew."""
    try:
        from pulse.brain.metacognition.agent_procedures import get_weak_domains
    except ImportError:
        return []
    warnings = []
    for member in crew:
        model = member.get("model", "")
        weak = get_weak_domains(model)
        for w in weak:
            if w["domain"] in domains:
                warnings.append({
                    "agent": model, "domain": w["domain"],
                    "success_rate": w["success_rate"], "total": w["total"],
                })
    return warnings


def _score_tier_alignment(crew, tasks):
    """Score Tier Alignment. Returns (score, warnings)."""
    if not crew or not tasks:
        return 0.5, []
    tier_needs = {"fast": 0, "standard": 0, "premium": 0}
    for t in tasks:
        tier_needs[_COMPLEXITY_TIER.get(t.get("complexity", "low"), "fast")] += 1
    crew_tiers = {"fast": 0, "standard": 0, "premium": 0}
    for m in crew:
        ct = m.get("tier", "fast")
        crew_tiers[ct] = crew_tiers.get(ct, 0) + m.get("count", 1)
    warnings = []
    score = 0.5
    if tier_needs["premium"] > 0 and crew_tiers.get("premium", 0) == 0:
        score -= 0.3
        warnings.append(str(tier_needs['premium']) + " high-complexity task(s) but NO premium agents in crew")
    elif tier_needs["premium"] > 0 and crew_tiers.get("premium", 0) > 0:
        score += 0.2
    needs_standard = tier_needs["standard"]
    has_standard_plus = crew_tiers.get("standard", 0) + crew_tiers.get("premium", 0)
    if needs_standard > 0 and has_standard_plus == 0:
        score -= 0.2
        warnings.append(str(needs_standard) + " standard-complexity task(s) but only fast-tier agents")
    elif needs_standard > 0 and has_standard_plus > 0:
        score += 0.15
    if tier_needs["premium"] == 0 and tier_needs["standard"] == 0:
        total_crew = sum(crew_tiers.values())
        if crew_tiers.get("fast", 0) == total_crew and total_crew > 0:
            score += 0.3
        elif crew_tiers.get("premium", 0) > 0:
            score -= 0.1
            warnings.append("All tasks are low-complexity — premium agents waste tokens")
    return max(0.0, min(1.0, score)), warnings


def _check_provider_limits(crew):
    """Check Ollama free tier cap. Returns (penalty, warnings, is_ollama_only)."""
    warnings = []
    penalty = 0.0
    ollama_count = sum(m.get("count", 1) for m in crew if m.get("provider", "") == "ollama")
    if ollama_count > OLLAMA_FREE_LIMIT:
        penalty = 0.15
        warnings.append(
            "Ollama free plan allows max " + str(OLLAMA_FREE_LIMIT)
            + " concurrent — crew has " + str(ollama_count) + " Ollama agents"
        )
    has_paid = any(m.get("provider", "") in ("claude", "gemini", "openai") for m in crew)
    is_ollama_only = not has_paid and ollama_count > 0
    return penalty, warnings, is_ollama_only


def _check_epistemic_conflict(crew, tasks):
    """Phase C Item 14: Prevent contradictory crew worldviews."""
    try:
        import json
        trust_file = _brain_utils.STATE_DIR / "agent_trust.json"
        if not trust_file.exists():
            return []
        data = json.loads(trust_file.read_text(encoding="utf-8"))
        agents_data = data.get("agents", {})
        has_complex = any(
            t.get("complexity") == "high" or t.get("recommended_tier") == "premium"
            for t in tasks
        )
        if not has_complex:
            return []
        crew_models = {m.get("model", ""): m for m in crew if m.get("model")}
        if len(crew_models) < 2:
            return []
        beliefs_by_model = {}
        for model in crew_models.keys():
            for agent_name, agent_info in agents_data.items():
                if agent_name.lower() in model.lower() or model.lower() in agent_name.lower():
                    beliefs = agent_info.get("beliefs", [])
                    if beliefs:
                        beliefs_by_model[model] = beliefs
                    break
        if len(beliefs_by_model) < 2:
            return []
        from pulse.core.llm_router import dispatch
        prompt = (
            "Analyze BeliefStates. Do any agents hold fundamentally contradictory worldviews "
            "that would cause conflict on a complex task? "
            "Return JSON: {\"conflict\": true/false, \"reason\": \"short explanation\"}. Beliefs: "
            + str(beliefs_by_model)
        )
        res = dispatch("fast", prompt)
        if res and res.get("conflict"):
            return ["Epistemic Conflict: " + str(res.get("reason", ""))]
        return []
    except Exception as e:
        log.debug("Epistemic check failed: " + str(e))
        return []
