#!/usr/bin/env python3
"""Decide whether AI observability deploy QA should run.

Input is a list of changed files via argv or stdin. The script prints matched
files and can write `needed=true|false` to a GitHub/Gitea Actions output file.
It exits 0 for both true and false so workflow control stays explicit.
"""

from __future__ import annotations

import argparse
import os
import re
from pathlib import Path


TRIGGER_PATTERNS = (
    r"^templates/admin/.*",
    r"^templates/ewoooc_base\.html$",
    r"^templates/components/_ewoooc_shell\.html$",
    r"^static/css/observability-system\.css$",
    r"^web/static/css/observability-system\.css$",
    r"^routes/admin_observability_routes\.py$",
    r"^scripts/check_observability_.*",
    r"^scripts/check_observability_suite\.sh$",
    r"^scripts/observability_contract\.py$",
    r"^scripts/quick_review\.sh$",
    r"^scripts/sync_observability_css\.py$",
    r"^docs/guides/observability_ui_governance\.md$",
    r"^docs/guides/deployment_sop\.md$",
)

SELF_TEST_POSITIVE = (
    "templates/admin/business_intel.html",
    "templates/ewoooc_base.html",
    "templates/components/_ewoooc_shell.html",
    "static/css/observability-system.css",
    "web/static/css/observability-system.css",
    "routes/admin_observability_routes.py",
    "scripts/check_observability_ui.py",
    "scripts/check_observability_pages.py",
    "scripts/check_observability_suite.sh",
    "scripts/observability_contract.py",
    "scripts/quick_review.sh",
    "scripts/sync_observability_css.py",
    "docs/guides/observability_ui_governance.md",
    "docs/guides/deployment_sop.md",
)

SELF_TEST_NEGATIVE = (
    "services/pricing_service.py",
    "docs/memory/history_logs.md",
    "README.md",
    "migrations/099_example.sql",
)


def normalize_paths(raw_paths: list[str]) -> list[str]:
    paths: list[str] = []
    for raw in raw_paths:
        for line in raw.splitlines():
            path = line.strip()
            if path:
                paths.append(path)
    return paths


def match_paths(paths: list[str]) -> list[str]:
    regexes = [re.compile(pattern) for pattern in TRIGGER_PATTERNS]
    return [path for path in paths if any(regex.search(path) for regex in regexes)]


def write_output(output_path: str | None, needed: bool) -> None:
    if not output_path:
        return
    path = Path(output_path)
    with path.open("a", encoding="utf-8") as handle:
        handle.write(f"needed={'true' if needed else 'false'}\n")


def run_self_test() -> int:
    positive_misses = [
        path for path in SELF_TEST_POSITIVE
        if path not in match_paths([path])
    ]
    negative_false_positives = [
        path for path in SELF_TEST_NEGATIVE
        if path in match_paths([path])
    ]

    if positive_misses or negative_false_positives:
        print("observability_deploy_gate_self_test=FAIL")
        if positive_misses:
            print("positive_misses:")
            for path in positive_misses:
                print(f"- {path}")
        if negative_false_positives:
            print("negative_false_positives:")
            for path in negative_false_positives:
                print(f"- {path}")
        return 1

    print("observability_deploy_gate_self_test=PASS")
    print(f"- positive_cases={len(SELF_TEST_POSITIVE)}")
    print(f"- negative_cases={len(SELF_TEST_NEGATIVE)}")
    return 0


def main() -> int:
    parser = argparse.ArgumentParser(description="Check observability deploy QA trigger")
    parser.add_argument("paths", nargs="*", help="Changed file paths")
    parser.add_argument("--stdin", action="store_true", help="Read changed paths from stdin")
    parser.add_argument("--self-test", action="store_true", help="Run built-in trigger tests")
    parser.add_argument(
        "--github-output",
        default=os.environ.get("GITHUB_OUTPUT"),
        help="Actions output file to append needed=true|false.",
    )
    args = parser.parse_args()

    if args.self_test:
        return run_self_test()

    raw_paths = list(args.paths)
    if args.stdin:
        import sys

        raw_paths.append(sys.stdin.read())

    paths = normalize_paths(raw_paths)
    matches = match_paths(paths)
    needed = bool(matches)

    write_output(args.github_output, needed)

    print(f"observability_qa_needed={'true' if needed else 'false'}")
    if matches:
        print("matched_files:")
        for path in matches:
            print(f"- {path}")
    else:
        print("matched_files: none")

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
