#!/usr/bin/env python3
"""Provision Slack/Teams routing for an installed app from code.

Chat subscriptions decide which channels and triggers land on which app.
Aiden resolves the app POST path from the installed app's discovery
manifest. Use them to stand up an on-call channel, mute a route during a
load test, or tear down a war-room subscription when the room closes.

Requires STACKGEN_URL, STACKGEN_TOKEN, and STACKGEN_WORKSPACE_ID.
The default target is an installed app. Pass --target-type agent --agent to
route the same subscription lifecycle at an agent instead.

Usage:
  export STACKGEN_URL=https://app.stackgen.com
  export STACKGEN_TOKEN=stackgen_…
  export STACKGEN_WORKSPACE_ID=<workspace-uuid>
  python examples/automation/chat-subscriptions.py --app-name sre
  python examples/automation/chat-subscriptions.py --target-type agent --agent my-oncall-agent
"""

from __future__ import annotations

import argparse
import os
import sys
import uuid

from stackgen import StackgenClient, StackgenConfig


def 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__)
    parser.add_argument(
        "--app-name",
        default="",
        help="Installed catalog app name. Required when --target-type is app.",
    )
    parser.add_argument(
        "--target-type",
        choices=("app", "agent"),
        default="app",
        help="Route matching chat events to an installed app or an agent",
    )
    parser.add_argument(
        "--agent",
        default="",
        help="Agent name. Required when --target-type is agent.",
    )
    parser.add_argument(
        "--channel-id",
        default="",
        help="Optional Slack/Teams channel id to constrain the selector",
    )
    parser.add_argument(
        "--bundle-name",
        default="",
        help="Optional AppChatSubscriptionSpec.name when the app declares multiple routes",
    )
    args = parser.parse_args()
    if args.target_type == "agent":
        if not args.agent:
            parser.error("--agent is required when --target-type agent")
        target_name = args.agent
    else:
        if not args.app_name:
            parser.error("--app-name is required when --target-type app")
        target_name = args.app_name

    client = StackgenClient(
        StackgenConfig(
            base_url=env("STACKGEN_URL"),
            api_token=env("STACKGEN_TOKEN"),
            workspace_id=env("STACKGEN_WORKSPACE_ID", "STACKGEN_PROJECT"),
        )
    )
    suffix = uuid.uuid4().hex[:8]
    body: dict = {
        "name": f"sdk-chat-sub-{suffix}",
        "target_type": args.target_type,
        "target_name": target_name,
        # channel_selector is required; tag matches Active-channels routing.
        "channel_selector": (
            {"channel_ids": [args.channel_id]}
            if args.channel_id
            else {"tag": "sdk-ci"}
        ),
        "trigger_types": ["mention"],
        "enabled": True,
    }
    if args.app_name:
        body["app_name"] = args.app_name
    if args.bundle_name:
        body["bundle_name"] = args.bundle_name

    created = client.aiden.create_chat_subscription(body)
    sub_id = str(created.get("id") or "")
    if not sub_id:
        raise SystemExit(f"create_chat_subscription missing id: {created}")
    print(f"created subscription id={sub_id} target_type={args.target_type}")

    try:
        got = client.aiden.get_chat_subscription(sub_id)
        print(f"get enabled={got.get('enabled')} endpoint={got.get('endpoint_path')}")

        list_kwargs = {"app_name": args.app_name} if args.app_name else {}
        listed = client.aiden.list_chat_subscriptions(**list_kwargs)
        print(f"list count={len(listed)}")

        toggled = client.aiden.toggle_chat_subscription(sub_id, {"enabled": False})
        print(f"toggled enabled={toggled.get('enabled')}")
    finally:
        try:
            client.aiden.delete_chat_subscription(sub_id)
            print(f"deleted subscription id={sub_id}")
        except Exception as exc:  # noqa: BLE001
            print(f"delete subscription id={sub_id} failed: {exc}", file=sys.stderr)
            raise

    return 0


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