#!/usr/bin/env python3
"""
M7 Agent Template Validation.

Runs live prompt checks against a local OpenAI-compatible llama-server when it is
available. By default, missing local model infrastructure is reported as SKIP so
cold static audits do not fail because no ODS stack is running. Set
ODS_REQUIRE_AGENT_TEMPLATE_SERVER=1 to make that condition a hard failure.
"""

from __future__ import annotations

import os
import sys
import time

import requests


LLAMA_SERVER_URL = os.environ.get("ODS_AGENT_TEMPLATE_BASE_URL", "http://localhost:8080")
MODEL = os.environ.get("ODS_AGENT_TEMPLATE_MODEL", "qwen2.5-32b-instruct")

if hasattr(sys.stdout, "reconfigure"):
    sys.stdout.reconfigure(encoding="utf-8", errors="replace")


TEMPLATES = {
    "code-assistant": {
        "system": "You are an expert programming assistant. Write clean, well-documented code.",
        "tests": [
            "Write a Python function to calculate factorial",
            "Debug this: for i in range(len(items)): print(items[i])",
        ],
    },
    "research-assistant": {
        "system": "You are a research assistant. Provide factual, well-sourced information.",
        "tests": [
            "Summarize what Python list comprehensions are",
            "Explain the difference between a stack and a queue",
        ],
    },
    "data-analyst": {
        "system": "You are a data analysis assistant. Help process and understand data.",
        "tests": [
            "How would you find the average of a list of numbers in Python?",
            "Explain what pandas DataFrame.describe() does",
        ],
    },
    "writing-assistant": {
        "system": "You are a writing assistant. Improve clarity and fix errors.",
        "tests": [
            "Fix the grammar: 'Their going to the store'",
            "Make this more concise: 'Due to the fact that it was raining, we decided to stay inside'",
        ],
    },
    "system-admin": {
        "system": "You are a system administration assistant. Help with Docker and Linux.",
        "tests": [
            "What command shows running Docker containers?",
            "How do you check disk usage on Linux?",
        ],
    },
}


def server_available() -> bool:
    """Return True when a local OpenAI-compatible model endpoint is reachable."""
    try:
        response = requests.get(f"{LLAMA_SERVER_URL}/v1/models", timeout=2)
        return response.status_code < 500
    except requests.RequestException:
        return False


def test_template(name: str, config: dict) -> dict:
    """Test a single template."""
    print(f"\n[TEST] {name}")

    results = {
        "template": name,
        "tests": [],
        "passed": 0,
        "failed": 0,
    }

    for test_prompt in config["tests"]:
        payload = {
            "model": MODEL,
            "messages": [
                {"role": "system", "content": config["system"]},
                {"role": "user", "content": test_prompt},
            ],
            "max_tokens": 200,
            "temperature": 0.7,
        }

        try:
            start = time.time()
            response = requests.post(
                f"{LLAMA_SERVER_URL}/v1/chat/completions",
                json=payload,
                timeout=30,
            )
            elapsed = (time.time() - start) * 1000

            if response.status_code == 200:
                data = response.json()
                content = data["choices"][0]["message"]["content"]

                # Basic validation: response should be non-empty and bounded.
                passed = 50 < len(content) < 2000

                results["tests"].append(
                    {
                        "prompt": test_prompt[:50],
                        "passed": passed,
                        "time_ms": elapsed,
                        "response_preview": content[:100],
                    }
                )

                if passed:
                    results["passed"] += 1
                    print(f"  [PASS] {test_prompt[:40]}... ({elapsed:.0f}ms)")
                else:
                    results["failed"] += 1
                    print(f"  [FAIL] {test_prompt[:40]}... (empty or too long)")
            else:
                results["tests"].append(
                    {
                        "prompt": test_prompt[:50],
                        "passed": False,
                        "error": f"HTTP {response.status_code}",
                    }
                )
                results["failed"] += 1
                print(f"  [FAIL] {test_prompt[:40]}... (HTTP {response.status_code})")

        except Exception as exc:  # noqa: BLE001 - diagnostic script should continue
            results["tests"].append(
                {
                    "prompt": test_prompt[:50],
                    "passed": False,
                    "error": str(exc),
                }
            )
            results["failed"] += 1
            print(f"  [FAIL] {test_prompt[:40]}... ({exc})")

    return results


def main() -> int:
    print("=" * 60)
    print("M7 Agent Template Validation")
    print(f"Testing {MODEL} at {LLAMA_SERVER_URL}")
    print("=" * 60)

    if not server_available():
        message = f"LLM server unavailable at {LLAMA_SERVER_URL}"
        if os.environ.get("ODS_REQUIRE_AGENT_TEMPLATE_SERVER") == "1":
            print(f"[FAIL] {message}")
            return 1
        print(f"[SKIP] {message}")
        print("Set ODS_REQUIRE_AGENT_TEMPLATE_SERVER=1 to make this a hard failure.")
        return 0

    all_results = []
    total_passed = 0
    total_failed = 0

    for name, config in TEMPLATES.items():
        result = test_template(name, config)
        all_results.append(result)
        total_passed += result["passed"]
        total_failed += result["failed"]

    print("\n" + "=" * 60)
    print("VALIDATION SUMMARY")
    print("=" * 60)

    for result in all_results:
        if result["failed"] == 0:
            status = "[PASS]"
        elif result["passed"] > 0:
            status = "[PARTIAL]"
        else:
            status = "[FAIL]"
        total = result["passed"] + result["failed"]
        print(f"{result['template']:20} {status} ({result['passed']}/{total} tests)")

    print("-" * 60)
    print(f"Total: {total_passed} passed, {total_failed} failed")

    if total_failed == 0:
        print("\n[PASS] All templates validated successfully!")
        return 0

    print(f"\n[FAIL] {total_failed} tests failed - review needed")
    return 1


if __name__ == "__main__":
    sys.exit(main())
