#!/usr/bin/env python3
# Copyright (c) 2025-2026 Kelevra Solutions (Pty) Ltd. All rights reserved.
# SPDX-License-Identifier: LicenseRef-Kelevra-Proprietary

"""Run the public Five Acts read journey with the Python SDK.

Default dry-run mode validates the scenario and prints the SDK calls without
using credentials. Live mode requires backend-held alpha credentials and a
server-minted tenant-context token.
"""

from __future__ import annotations

import argparse
import json
import os
from pathlib import Path
from typing import Any


def load_scenario(path: Path) -> dict:
    return json.loads(path.read_text(encoding="utf-8"))


def print_plan(scenario: dict) -> None:
    print(f"scenario={scenario['scenario']}")
    print(f"canonical_story_revision={scenario['canonical_story']['revision']}")
    for step in scenario["example_flow"]:
        print(f"- {step}")


def collection_items(collection: Any) -> list[Any]:
    """Return first-page resource rows from SDK page or resource-list shapes."""
    if isinstance(collection, dict):
        data = collection.get("data")
        if isinstance(data, list):
            return data
        if data is None:
            return []
        return [data]

    page_items = getattr(collection, "items", None)
    if isinstance(page_items, list):
        return page_items

    if isinstance(collection, list | tuple):
        return list(collection)

    try:
        return list(collection)
    except TypeError:
        return []


def resource_id(resource: Any) -> str:
    value = resource.get("id") if isinstance(resource, dict) else getattr(resource, "id", None)
    if not isinstance(value, str) or not value:
        raise RuntimeError("SDK list item did not include an id")
    return value


def run_live(args: argparse.Namespace, scenario: dict) -> None:
    from axiom import AxiomClient

    token = os.environ["AXIOM_ACCESS_TOKEN"]
    tenant_context = os.environ["AXIOM_TENANT_CONTEXT"]
    client = AxiomClient(
        args.base_url,
        bearer_token=token,
        tenant_context_token=tenant_context,
    )

    print_plan(scenario)
    health = client.health.list()
    print(f"health.request_id={health.meta.request_id}")

    tenants = client.me.tenants()
    print(f"tenants.request_id={tenants.meta.request_id}")

    parties = client.parties.list(**{"page[size]": args.limit})
    party_items = collection_items(parties)
    print(f"parties.count={len(party_items)} request_id={parties.meta.request_id}")
    if party_items:
        party = client.parties.get(resource_id(party_items[0]))
        print(f"party.id={party['id']} request_id={party.meta.request_id}")

    policies = client.policies.list(**{"page[size]": args.limit})
    policy_items = collection_items(policies)
    print(f"policies.count={len(policy_items)} request_id={policies.meta.request_id}")
    if policy_items:
        policy = client.policies.get(resource_id(policy_items[0]))
        print(f"policy.id={policy['id']} request_id={policy.meta.request_id}")

    claim_compatibility = client.claims.list(**{"page[size]": args.limit})
    assertion_items = collection_items(claim_compatibility)
    print(
        "claim_compatibility.count="
        f"{len(assertion_items)} request_id={claim_compatibility.meta.request_id}"
    )
    if assertion_items:
        assertion_compatibility = client.claims.get(resource_id(assertion_items[0]))
        print(
            "claim_compatibility.id="
            f"{assertion_compatibility['id']} request_id={assertion_compatibility.meta.request_id}"
        )


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--scenario", type=Path, default=Path(__file__).resolve().parents[1] / "scenario.json"
    )
    parser.add_argument("--base-url", default="https://api.afr-dev.axiom.express")
    parser.add_argument("--limit", type=int, default=5)
    parser.add_argument("--dry-run", action="store_true")
    args = parser.parse_args()

    scenario = load_scenario(args.scenario)
    if args.dry_run:
        print_plan(scenario)
        print("dry_run=true")
        print("live_requirements=AXIOM_ACCESS_TOKEN,AXIOM_TENANT_CONTEXT")
        return 0

    missing = [
        name for name in ("AXIOM_ACCESS_TOKEN", "AXIOM_TENANT_CONTEXT") if not os.getenv(name)
    ]
    if missing:
        parser.error(f"missing required environment variables for live mode: {', '.join(missing)}")
    run_live(args, scenario)
    return 0


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