#!/usr/bin/env python3
"""Create a Linear-style webhook acknowledgement.

Providers such as Linear expect HTTP 200 (not 202) and may send signature
headers that apps need on forward. This sample:

1. Creates a webhook with response_status=200 and custom ack headers
2. Triggers it with a Linear-Signature header
3. Prints the acknowledgement status/headers (processing stays async)

Usage:
  export STACKGEN_URL=https://app.stackgen.com
  export STACKGEN_TOKEN=stackgen_…
  export STACKGEN_WORKSPACE_ID=<workspace-uuid>
  python examples/automation/webhook-ack-headers.py --agent my-oncall-agent
  # Empty CI workspaces: prefer a published workflow (agents need an integration).
  python examples/automation/webhook-ack-headers.py --workflow my-note-workflow
"""

from __future__ import annotations

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

from stackgen import StackgenClient, StackgenConfig


def require_env(name: str, *fallbacks: str) -> str:
    for key in (name, *fallbacks):
        value = (os.environ.get(key) or "").strip()
        if value:
            return value
    raise SystemExit(f"missing env {name}")


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    target = parser.add_mutually_exclusive_group(required=True)
    target.add_argument("--agent", help="Existing agent name")
    target.add_argument("--workflow", help="Existing workflow name")
    parser.add_argument(
        "--message",
        default="sdk: acknowledge Linear-style webhook and reply Done",
        help="Webhook action prompt",
    )
    args = parser.parse_args()
    target_type = "agent" if args.agent else "workflow"
    target_name = args.agent or args.workflow

    base_url = require_env("STACKGEN_URL").rstrip("/")
    org_id = require_env("STACKGEN_WORKSPACE_ID", "STACKGEN_PROJECT")
    client = StackgenClient(
        StackgenConfig(
            base_url=base_url,
            api_token=require_env("STACKGEN_TOKEN"),
            workspace_id=org_id,
        )
    )
    suffix = uuid.uuid4().hex[:8]
    webhook_id = ""

    try:
        wh = client.aiden.create_webhook(
            {
                "name": f"sdk-ack-{suffix}",
                "target_type": target_type,
                "target_name": target_name,
                "action": args.message,
                "enabled": True,
                # Providers that reject 202 can require 200.
                "response_status": 200,
                "response_headers": {
                    "X-Ack-Source": "stackgen-sdk",
                    "X-Provider-Hint": "linear-style",
                },
            }
        )
        webhook_id = str(wh.get("id") or "")
        token = str(wh.get("token") or "")
        print(f"created webhook id={webhook_id} response_status={wh.get('response_status')}")
        print(f"response_headers={json.dumps(wh.get('response_headers') or {})}")
        if not token:
            raise SystemExit("createWebhook did not return a token")

        # Trigger with a provider signature header. Ack is immediate; the agent
        # run continues asynchronously.
        url = f"{base_url}/guild/api/v1/webhooks/trigger?orgId={org_id}"
        req = urllib.request.Request(
            url,
            data=json.dumps({"action": "issue.create", "source": "sdk-ack"}).encode("utf-8"),
            method="POST",
            headers={
                "Authorization": f"Bearer {token}",
                "Accept": "application/json",
                "Content-Type": "application/json",
                "Linear-Signature": "sdk-demo-sig",
            },
        )
        with urllib.request.urlopen(req, timeout=60) as resp:
            body = resp.read().decode("utf-8")
            print(f"trigger status={resp.status}")
            print(f"trigger ack X-Ack-Source={resp.headers.get('X-Ack-Source')}")
            print(f"trigger ack X-Provider-Hint={resp.headers.get('X-Provider-Hint')}")
            print(f"trigger body={body}")
            if resp.status != 200:
                raise SystemExit(f"expected acknowledgement HTTP 200, got {resp.status}")
    except urllib.error.HTTPError as err:
        detail = err.read().decode("utf-8", errors="replace")
        raise SystemExit(f"trigger failed status={err.code} body={detail}") from err
    finally:
        if webhook_id:
            try:
                client.aiden.delete_webhook(webhook_id)
                print(f"deleted webhook id={webhook_id}")
            except Exception as cleanup_err:  # noqa: BLE001 — best-effort teardown
                print(f"cleanup delete_webhook failed: {cleanup_err}", file=sys.stderr)

    return 0


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