#!/usr/bin/env python3
"""SRE: list alerts → investigate → wait for the RCA.

Proves the alert-already-in-inbox path. Use --list-only when the tenant
has no alerts yet (HTTP 200 + empty list is success).

Documented at:
  https://appcd-dev.github.io/stackgen-sdk/code-samples/sre-investigate-alert/

Credentials (flags override env):
  STACKGEN_URL, STACKGEN_TOKEN, STACKGEN_WORKSPACE_ID (or STACKGEN_ORG_ID / STACKGEN_PROJECT)

Usage:

  pip install -e ./clients/python

  python examples/sre/investigate-alert.py --list-only

  python examples/sre/investigate-alert.py --q 'checkout' --poll

  python examples/sre/investigate-alert.py --alert-id <uuid> --poll
"""

from __future__ import annotations

import argparse
import json
import os
import sys

from stackgen import StackgenClient, StackgenConfig
from stackgen.errors import StackgenError


def _org_id(cli_value: str | None) -> str:
    return (
        (cli_value or "").strip()
        or os.environ.get("STACKGEN_WORKSPACE_ID", "").strip()
        or os.environ.get("STACKGEN_ORG_ID", "").strip()
        or os.environ.get("STACKGEN_PROJECT", "").strip()
        or os.environ.get("STACKGEN_PROJECT_ID", "").strip()
    )


def _config(args: argparse.Namespace) -> StackgenConfig:
    base = (args.base_url or os.environ.get("STACKGEN_URL", "")).strip()
    token = (args.api_token or os.environ.get("STACKGEN_TOKEN", "")).strip()
    org = _org_id(args.workspace_id)
    if not base or not token:
        raise SystemExit(
            "set --base-url/--api-token or STACKGEN_URL / STACKGEN_TOKEN"
        )
    return StackgenConfig(
        base_url=base,
        api_token=token,
        workspace_id=org,
        timeout_seconds=args.timeout_seconds,
        poll_interval_seconds=args.poll_interval_seconds,
    )


def _alert_rows(payload: object) -> list[dict]:
    if not isinstance(payload, dict):
        return []
    rows = payload.get("alerts") or payload.get("items") or []
    return [r for r in rows if isinstance(r, dict)]


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--base-url", default="")
    parser.add_argument("--api-token", default="")
    parser.add_argument("--workspace-id",
        "--org-id", default="")
    parser.add_argument("--status", default="active", help="Alert status filter")
    parser.add_argument("--q", default="checkout", help="Alert search query")
    parser.add_argument("--alert-id", default="", help="Skip list; investigate this id")
    parser.add_argument(
        "--list-only",
        action="store_true",
        help="List matching alerts and exit 0 (empty list is OK)",
    )
    parser.add_argument(
        "--poll",
        action="store_true",
        help="After investigate, wait until the RCA is ready",
    )
    parser.add_argument(
        "--export-session",
        action="store_true",
        help="If guild_session_id is set, call aiden.export_session(parts=report)",
    )
    parser.add_argument("--timeout-seconds", type=int, default=1800)
    parser.add_argument("--poll-interval-seconds", type=int, default=5)
    parser.add_argument(
        "--operator-message",
        default="Investigate checkout CPU in prod",
    )
    args = parser.parse_args()

    client = StackgenClient(_config(args))

    alert_id = args.alert_id.strip()
    if not alert_id:
        alerts = client.sre.list_alerts(status=args.status, q=args.q)
        if not isinstance(alerts, dict):
            print(f"error: unexpected list_alerts shape: {alerts!r}", file=sys.stderr)
            return 1
        items = _alert_rows(alerts)
        print("list_alerts:", json.dumps(alerts, indent=2, default=str))
        print(f"count={len(items)}", file=sys.stderr)
        if args.list_only:
            return 0
        if not items:
            print(
                "error: no matching alert (pass --alert-id or use --list-only)",
                file=sys.stderr,
            )
            return 1
        alert_id = str(items[0].get("id") or "")
        if not alert_id:
            print("error: alert item missing id", file=sys.stderr)
            return 1

    if not args.poll:
        started = client.sre.investigate_alert(
            alert_id,
            operator_message=args.operator_message,
        )
        print("investigate:", json.dumps(started, indent=2, default=str))
        return 0

    investigation = client.sre.investigate_alert_and_wait(
        alert_id,
        operator_message=args.operator_message,
    )
    print("investigation:", json.dumps(investigation, indent=2, default=str))

    plain = investigation.get("structured_rca") if isinstance(investigation, dict) else None
    if isinstance(plain, dict):
        summary = plain.get("plain_summary")
        if isinstance(summary, dict):
            print(
                "plain_summary:",
                json.dumps(summary, indent=2, default=str),
            )
        root = plain.get("root_cause")
        if root:
            print(f"root_cause={root}", file=sys.stderr)

    session_id = investigation.get("guild_session_id") if isinstance(investigation, dict) else None
    if args.export_session and session_id:
        export = client.aiden.export_session(str(session_id), parts="report")
        print("export:", json.dumps(export, indent=2, default=str))
    return 0


if __name__ == "__main__":
    try:
        raise SystemExit(main())
    except StackgenError as exc:
        print(f"error: {exc}", file=sys.stderr)
        if "401" in str(exc) or "missing identity" in str(exc).lower():
            print(
                "hint: SRE /app/sre routes need the edge to inject workspace "
                "identity (X-Appcd-Org). If Aiden works but SRE returns 401, "
                "the mothership app proxy is not forwarding PAT identity.",
                file=sys.stderr,
            )
        raise SystemExit(1)
