"""Core license bootstrap flow.

When called, this module:
1. Loads config (from params or .cgt_license.json)
2. Loads Guard.dll
3. Initializes guard
4. Checks for stored license key, or prompts user
5. Activates
6. Gets lease
7. Starts watchdog
8. Returns guard instance
"""

import sys
import logging
from ._guard import GuardFFI, LicenseError, InvalidKeyError
from ._config import load_config, build_config
from ._dialogs import prompt_license_key, show_error_and_exit
from ._watchdog import start_watchdog

logger = logging.getLogger("cgt_license")


def bootstrap(
    server_url: str | None = None,
    product_id: str | None = None,
    guard_dll: str | None = None,
    app_name: str | None = None,
    logo: str | None = None,
) -> GuardFFI:
    """Run the full license bootstrap flow.

    Args:
        server_url: License server URL (e.g. "http://localhost:8000")
        product_id: Product UUID from the server
        guard_dll:  Path to cgt_guard.dll (auto-detected if omitted)
        app_name:   App name shown in dialogs
        logo:       Path to logo image for dialogs

    If server_url and product_id are provided, no config file is needed.
    Otherwise falls back to .cgt_license.json next to the app.

    On any failure: show error dialog and sys.exit(1).
    """
    print("[CGT] Loading config...", flush=True)
    try:
        if server_url and product_id:
            config = build_config(
                server_url=server_url,
                product_id=product_id,
                guard_dll=guard_dll,
                app_name=app_name,
                logo=logo,
            )
        else:
            config = load_config()
    except (FileNotFoundError, ValueError) as e:
        show_error_and_exit(str(e))

    print(f"[CGT] Loading Guard DLL: {config['guard_dll']}", flush=True)
    try:
        guard = GuardFFI(config["guard_dll"])
    except OSError as e:
        show_error_and_exit(f"Cannot load Guard.dll: {e}")

    print(f"[CGT] Init guard (server={config['server_url']}, product={config['product_id']})...", flush=True)
    try:
        guard.init(config["server_url"], config["product_id"])
    except LicenseError as e:
        show_error_and_exit(f"Guard init failed: {e}")

    print("[CGT] Init OK. Trying lease...", flush=True)

    # Try activation -- may already be stored from previous run
    activated = False
    try:
        # Guard.init() loads stored license key internally.
        # Try lease directly -- if it works, we're already activated.
        guard.lease()
        activated = True
        print("[CGT] Lease OK (already activated).", flush=True)
    except LicenseError as e:
        # Need to activate first
        print(f"[CGT] Lease failed ({e}), need activation.", flush=True)

    if not activated:
        # Prompt for license key
        print("[CGT] Prompting for license key...", flush=True)
        license_key = prompt_license_key(
            title=config.get("app_name", "License Activation"),
            logo_path=config.get("logo"),
        )
        if not license_key:
            show_error_and_exit(
                "No license key provided. Application cannot start."
            )

        print(f"[CGT] Activating key: {license_key[:4]}...", flush=True)
        try:
            guard.activate(license_key)
        except InvalidKeyError:
            show_error_and_exit("Invalid license key.")
        except LicenseError as e:
            show_error_and_exit(f"Activation failed: {e}")

        print("[CGT] Activation OK. Getting lease...", flush=True)
        try:
            guard.lease()
        except LicenseError as e:
            show_error_and_exit(f"Could not obtain license lease: {e}")

    # Start watchdog
    start_watchdog(guard)

    print("[CGT] Bootstrap complete — app is authorized.", flush=True)
    return guard
