#!/usr/bin/env python3
"""arq-anthropic — Anthropic API adapter for ARQERA mesh.

Wave B of admin-privileged Twin per-worker cost attribution.
Substrate-attests every call. Per-workforce cost queries supported.

v0 verbs:
  arq-anthropic usage org [--days N]      — org-wide usage
  arq-anthropic usage by-key [--days N]   — per-key usage (groups by api-key)
  arq-anthropic key list                  — list API keys (admin scope only)
"""
from __future__ import annotations
import argparse, json, os, sys, time, urllib.request, urllib.error
from datetime import UTC, datetime, timedelta
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from _arq_provider_base import sops_extract, emit_act, call_with_audit, print_json, handle_meta_flags

PROVIDER = "anthropic"
REQUIRED_SCOPES: dict[str, list[str]] = {
    # Anthropic Admin-API endpoints — require an Anthropic Admin-class key
    # (distinct from standard API keys). Anthropic does not publish per-verb
    # scope strings; all admin endpoints share the single "admin" capability.
    "usage org": ["admin"],
    "usage by-key": ["admin"],
    "key list": ["admin"],
}
API_BASE = "https://api.anthropic.com"


def _api_key() -> str | None:
    return (os.environ.get("ANTHROPIC_API_KEY") or
            sops_extract('["arqera_twin_admin"]["anthropic"]["value"]') or
            sops_extract('["anthropic"]["anthropic_api_key"]'))


def _api_get(path: str, params: dict | None = None) -> tuple[int, dict | str]:
    key = _api_key()
    if not key:
        return 401, "no anthropic key in env/SOPS"
    if params:
        from urllib.parse import urlencode
        path = f"{path}?{urlencode(params)}"
    req = urllib.request.Request(
        f"{API_BASE}{path}",
        headers={
            "x-api-key": key,
            "anthropic-version": "2023-06-01",
            "anthropic-beta": "messages-2023-12-15",
        },
    )
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            return resp.status, json.loads(resp.read())
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode("utf-8", errors="ignore")
    except Exception as e:
        return 500, str(e)


def _cmd_usage_org(args) -> int:
    end = datetime.now(UTC).date()
    start = end - timedelta(days=args.days)
    code, data = _api_get("/v1/organizations/usage_report/messages", {
        "starting_at": start.isoformat() + "T00:00:00Z",
        "ending_at": end.isoformat() + "T23:59:59Z",
    })
    if code != 200:
        sys.stderr.write(f"HTTP {code}: {data}\n")
        return 1
    return print_json(data)


def _cmd_usage_by_key(args) -> int:
    end = datetime.now(UTC).date()
    start = end - timedelta(days=args.days)
    code, data = _api_get("/v1/organizations/usage_report/messages", {
        "starting_at": start.isoformat() + "T00:00:00Z",
        "ending_at": end.isoformat() + "T23:59:59Z",
        "group_by": "api_key_id",
    })
    if code != 200:
        sys.stderr.write(f"HTTP {code}: {data}\n")
        return 1
    return print_json(data)


def _cmd_key_list(args) -> int:
    code, data = _api_get("/v1/organizations/api_keys")
    if code != 200:
        sys.stderr.write(f"HTTP {code}: {data}\n")
        return 1
    return print_json(data)


def main() -> int:
    handle_meta_flags(PROVIDER, REQUIRED_SCOPES)
    p = argparse.ArgumentParser(prog="arq-anthropic")
    sub = p.add_subparsers(dest="cmd", required=True)
    s_u = sub.add_parser("usage")
    s_u_sub = s_u.add_subparsers(dest="action", required=True)
    s_u_org = s_u_sub.add_parser("org"); s_u_org.add_argument("--days", type=int, default=30); s_u_org.set_defaults(func=_cmd_usage_org, verb="usage org")
    s_u_key = s_u_sub.add_parser("by-key"); s_u_key.add_argument("--days", type=int, default=30); s_u_key.set_defaults(func=_cmd_usage_by_key, verb="usage by-key")
    s_k = sub.add_parser("key")
    s_k_sub = s_k.add_subparsers(dest="action", required=True)
    s_k_l = s_k_sub.add_parser("list"); s_k_l.set_defaults(func=_cmd_key_list, verb="key list")
    args = p.parse_args()
    return call_with_audit(PROVIDER, args.verb, args.func, args)


if __name__ == "__main__":
    sys.exit(main())
