#!/usr/bin/env python3
"""Post a condensed security dashboard summary to a webhook or stdout."""

from __future__ import annotations

import argparse
import json
import os
import pathlib
import sys
import urllib.error
import urllib.request

from tnfr.utils import json_dumps


def parse_args(argv: list[str]) -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument(
        "--summary-json",
        type=pathlib.Path,
        required=True,
        help="Path to the JSON summary generated by generate_security_dashboard.py",
    )
    parser.add_argument(
        "--summary-md",
        type=pathlib.Path,
        default=None,
        help="Path to the generated Markdown file (optional reference)",
    )
    parser.add_argument(
        "--webhook-url",
        type=str,
        default=None,
        help="Webhook URL (Slack or other) to publish the summary",
    )
    return parser.parse_args(argv)


def build_message(payload: dict, markdown_path: pathlib.Path | None) -> str:
    generated_at = payload.get("generated_at", "unknown")
    run_url = payload.get("run_url")
    tools = payload.get("tools", {})
    dependabot = payload.get("dependabot", {})

    lines = [f"Security dashboard · {generated_at}"]
    if run_url:
        lines.append(f"Consolidated run: {run_url}")

    if tools:
        for tool_name in sorted(tools.keys()):
            data = tools[tool_name]
            if data.get("missing"):
                lines.append(f"- {tool_name}: no artifacts in the run")
                continue
            total = data.get("total", 0)
            lines.append(
                "- {tool}: {total} findings (C:{critical} H:{high} M:{medium} L:{low})".format(
                    tool=tool_name,
                    total=total,
                    critical=data.get("critical", 0),
                    high=data.get("high", 0),
                    medium=data.get("medium", 0),
                    low=data.get("low", 0),
                )
            )
    else:
        lines.append("- No artifacts found to consolidate")

    if dependabot.get("total") is None:
        if dependabot.get("error"):
            lines.append(f"Dependabot: {dependabot['error']}")
    else:
        lines.append(
            "Dependabot: {total} alerts (C:{critical} H:{high} M:{medium} L:{low})".format(
                total=dependabot.get("total", 0),
                critical=dependabot.get("critical", 0),
                high=dependabot.get("high", 0),
                medium=dependabot.get("medium", 0),
                low=dependabot.get("low", 0),
            )
        )
        if dependabot.get("url"):
            lines.append(f"Dependabot dashboard: {dependabot['url']}")

    if markdown_path:
        lines.append(f"Markdown report: {markdown_path}")

    message = "\n".join(lines)
    if len(message) > 3900:
        message = message[:3897] + "…"
    return message


def post_message(webhook: str, message: str) -> None:
    data = json_dumps({"text": message}, to_bytes=True)
    request = urllib.request.Request(
        webhook,
        data=data,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(
        request, timeout=15
    ) as response:  # pragma: no cover - network
        response.read()


def main(argv: list[str] | None = None) -> int:
    args = parse_args(argv or sys.argv[1:])
    if not args.summary_json.exists():
        raise SystemExit(f"Missing JSON summary: {args.summary_json}")
    payload = json.loads(args.summary_json.read_text(encoding="utf-8"))
    webhook = args.webhook_url or os.environ.get("SECURITY_WEBHOOK_URL")
    message = build_message(payload, args.summary_md)
    print(message)
    if webhook:
        try:
            post_message(webhook, message)
        except urllib.error.URLError as exc:  # pragma: no cover - network errors
            print(f"Failed to publish the summary: {exc}", file=sys.stderr)
            return 1
    return 0


if __name__ == "__main__":  # pragma: no cover - CLI entry point
    raise SystemExit(main())
