"""Seed the Moodle SSO OAuth2 client Application (idempotent).

Reproduces, as code, the OAuth `Application` we created by hand when wiring
"Log in with IILMP" — so production (and any rebuild) is repeatable. The same
client id/secret must be given to the Moodle OAuth2 issuer (see
`scripts/configure_moodle_prod.php`), which is why both read the same env vars.
"""
import os

from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
from oauth2_provider.models import get_application_model


class Command(BaseCommand):
    help = (
        "Create/update the Moodle SSO OAuth2 Application (idempotent). Reads "
        "MOODLE_SSO_CLIENT_ID / MOODLE_SSO_CLIENT_SECRET from the environment; the "
        "redirect URI is derived from MOODLE_HOST (or --redirect-uri)."
    )

    def add_arguments(self, parser):
        parser.add_argument(
            "--client-id", default=os.getenv("MOODLE_SSO_CLIENT_ID", "moodle-sso"),
            help="OAuth client_id (default env MOODLE_SSO_CLIENT_ID or 'moodle-sso').",
        )
        parser.add_argument(
            "--client-secret", default=os.getenv("MOODLE_SSO_CLIENT_SECRET", ""),
            help="OAuth client secret (default env MOODLE_SSO_CLIENT_SECRET). Stored hashed.",
        )
        parser.add_argument(
            "--redirect-uri", default=os.getenv("MOODLE_SSO_REDIRECT_URI", ""),
            help="Moodle OAuth callback. Defaults to https://<MOODLE_HOST>/admin/oauth2callback.php.",
        )
        parser.add_argument("--name", default="Moodle SSO")

    def handle(self, *args, **options):
        Application = get_application_model()

        client_id = options["client_id"].strip()
        client_secret = options["client_secret"].strip()
        redirect_uri = (options["redirect_uri"] or self._default_redirect()).strip()

        if not client_secret:
            raise CommandError(
                "MOODLE_SSO_CLIENT_SECRET is required (or pass --client-secret)."
            )
        if not redirect_uri:
            raise CommandError(
                "Could not determine the Moodle callback — set MOODLE_SSO_REDIRECT_URI "
                "or MOODLE_HOST."
            )

        app, created = Application.objects.get_or_create(
            client_id=client_id, defaults={"name": options["name"]}
        )
        app.name = options["name"]
        app.client_type = "confidential"
        app.authorization_grant_type = "authorization-code"
        app.redirect_uris = redirect_uri
        # First-party trusted app — skip the consent screen for a seamless hand-off.
        app.skip_authorization = True
        # HS256 id_token signed with the client secret (no RSA key needed for the
        # userinfo-based Moodle flow; OIDC_RSA_PRIVATE_KEY still powers jwks).
        app.algorithm = "HS256"
        app.client_secret = client_secret  # hashed on save (HASH_CLIENT_SECRET)
        app.save()

        self.stdout.write(self.style.SUCCESS(
            f"{'Created' if created else 'Updated'} OAuth Application "
            f"'{app.name}' (client_id={app.client_id}, redirect={app.redirect_uris}, "
            f"skip_authorization={app.skip_authorization})."
        ))

    @staticmethod
    def _default_redirect():
        host = (getattr(settings, "MOODLE_HOST", "") or "").strip()
        if not host:
            return ""
        base = host.rstrip("/") if host.startswith(("http://", "https://")) else f"https://{host}"
        return f"{base}/admin/oauth2callback.php"
