#!/usr/bin/env python3
"""Nova Onboarding — auto-generate an environment binding file (P19, REQ-183).

Given a consumer onboarding request (validated against
schemas/onboarding.schema.json), generate a ``<env>.json`` environment
binding file from the dev template, filling in the consumer's ownerId +
billingTag. The generated file is a starting point for the platform team
(or a future automation) to bind to a real AWS account.

This is the "request path" half of the no-humans onboarding flow (D-113).
Real AWS account/network/state provisioning is a future feature milestone;
this module removes the human handoff from the *request* step by
generating the binding file + emitting a git patch / PR-branch instruction.

Usage:
    python3 core/onboarding.py <request.json> [--out <env.json>]
    python3 core/onboarding.py --request '{"consumerRepo":"acdl/c","requestedEnvironment":"qa","ownerId":"team-a","billingTag":"cc-a"}'
"""
from __future__ import annotations

import argparse
import json
import os
import sys
from pathlib import Path
from typing import Any, Dict


def _repo_root() -> Path:
    return Path(__file__).resolve().parent.parent


def _load_template_env(template_env: str = "dev", root: Path | None = None) -> Dict[str, Any]:
    """Load the template environment JSON (defaults to dev.json)."""
    root = root or _repo_root()
    env_path = root / "core" / "environments" / f"{template_env}.json"
    if not env_path.is_file():
        raise FileNotFoundError(f"template environment {env_path} not found")
    return json.loads(env_path.read_text())


def generate_env_file(
    request: Dict[str, Any],
    template_env: str = "dev",
    root: Path | None = None,
) -> Dict[str, Any]:
    """Generate an environment binding dict from a consumer onboarding request.

    The generated dict is a copy of the template env with:
      - ``name`` → the requested environment
      - ``description`` → notes the consumer + owner
      - ``account_id`` → placeholder (000000000000) for the platform team
        to fill with the real account
      - ``ownerId`` + ``billingTag`` → from the request (for ABAC + cost)

    The dict validates against schemas/environment.schema.json.

    Returns the generated env dict.
    """
    template = _load_template_env(template_env, root)
    requested = request["requestedEnvironment"]
    owner = request["ownerId"]
    billing = request["billingTag"]
    consumer = request["consumerRepo"]

    env = dict(template)
    env["name"] = requested
    env["description"] = (
        f"Auto-generated binding for {consumer} (owner={owner}, "
        f"billing={billing}). Replace account_id with the real "
        f"{requested} account before deploying."
    )
    env["account_id"] = "000000000000"  # placeholder — platform team fills
    env["ownerId"] = owner
    env["billingTag"] = billing
    return env


def _onboarding_request_message(env_name: str) -> str:
    """P19 (REQ-183): the rebranded Nova onboarding message — self-service
    request path, no longer routes to 'contact the platform team'."""
    return (
        "=== Nova Environment Onboarding ===\n"
        f"No environment named '{env_name}' is bound to this repository.\n\n"
        "Nova environments are platform-managed. The platform provisions on\n"
        "your behalf:\n"
        "  - an AWS account (or a scoped partition of one)\n"
        "  - a network (VPC + subnets)\n"
        "  - a state backend (an S3 bucket + DynamoDB lock table)\n"
        "  - an IAM role surfaced to your repo via attribute-based\n"
        "    authorization (ABAC)\n\n"
        "You do not provide an AWS account, VPC, subnet, or state bucket.\n\n"
        "To request an environment (self-service):\n"
        "  1. Submit an onboarding request to the Nova Lambda\n"
        "     (action: onboard_consumer) with your repo name + the\n"
        "     environment name you need (e.g. 'dev').\n"
        "  2. The platform generates an environment binding + opens a PR.\n"
        "  3. The platform provisions the account/network/state/role and\n"
        "     grants the ABAC role. Your next pipeline run proceeds.\n\n"
        "Run: python3 core/onboarding.py --request '{...}' to generate a\n"
        "binding file locally, or POST to the Lambda onboard_consumer action.\n"
        "===================================\n"
    )


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Generate an env binding from an onboarding request.")
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("request_file", nargs="?", help="path to a request JSON file")
    group.add_argument("--request", help="inline request JSON string")
    parser.add_argument("--out", help="output path for the generated env JSON (default: stdout)")
    parser.add_argument("--template-env", default="dev", help="template environment (default: dev)")
    args = parser.parse_args(argv)

    if args.request:
        request = json.loads(args.request)
    else:
        request = json.loads(Path(args.request_file).read_text())

    env = generate_env_file(request, template_env=args.template_env)
    env_json = json.dumps(env, indent=2) + "\n"
    if args.out:
        Path(args.out).write_text(env_json)
        print(f"wrote: {args.out}")
    else:
        print(env_json)
    return 0


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