# Generated by Django 4.2.20 on 2025-04-04 08:26

from django.db import migrations
from glom import glom

from ..constants import (
    OIDC_ADMIN_CONFIG_IDENTIFIER,
    OIDC_ADMIN_PROVIDER_CONFIG_IDENTIFIER,
)


def move_data_backwards(apps, schema_editor):
    OIDCClient = apps.get_model("mozilla_django_oidc_db", "OIDCClient")
    OpenIDConnectConfig = apps.get_model(
        "mozilla_django_oidc_db", "OpenIDConnectConfig"
    )
    Group = apps.get_model("auth", "Group")

    # There can be multiple configurations, but we pick one
    new_config = OIDCClient.objects.filter(
        identifier=OIDC_ADMIN_CONFIG_IDENTIFIER
    ).first()
    if not new_config:
        return

    if not new_config.oidc_provider:
        # The model was likely never configured. We cannot migrate data backwards because
        # we don't have a fully configured client/provider.
        return

    username_claim_mapping = []
    if other_user_mappings := glom(
        new_config.options, "user_settings.claim_mappings", default={}
    ):
        username_claim_mapping = other_user_mappings["username"]
        del other_user_mappings["username"]

    group_settings = new_config.options.get("groups_settings", {})

    old_config = OpenIDConnectConfig.objects.create(
        enabled=new_config.enabled,
        # Provider settings
        oidc_op_discovery_endpoint=(
            new_config.oidc_provider.oidc_op_discovery_endpoint
        ),
        oidc_op_jwks_endpoint=new_config.oidc_provider.oidc_op_jwks_endpoint,
        oidc_op_authorization_endpoint=(
            new_config.oidc_provider.oidc_op_authorization_endpoint
        ),
        oidc_op_token_endpoint=new_config.oidc_provider.oidc_op_token_endpoint,
        oidc_op_user_endpoint=new_config.oidc_provider.oidc_op_user_endpoint,
        oidc_op_logout_endpoint=(new_config.oidc_provider.oidc_op_logout_endpoint),
        oidc_token_use_basic_auth=new_config.oidc_provider.oidc_token_use_basic_auth,
        oidc_use_nonce=new_config.oidc_provider.oidc_use_nonce,
        oidc_nonce_size=new_config.oidc_provider.oidc_nonce_size,
        oidc_state_size=new_config.oidc_provider.oidc_state_size,
        # Client settings
        oidc_rp_client_id=new_config.oidc_rp_client_id,
        oidc_rp_client_secret=new_config.oidc_rp_client_secret,
        oidc_rp_sign_algo=new_config.oidc_rp_sign_algo,
        oidc_rp_scopes_list=new_config.oidc_rp_scopes_list,
        oidc_rp_idp_sign_key=new_config.oidc_rp_idp_sign_key,
        oidc_keycloak_idp_hint=new_config.oidc_keycloak_idp_hint,
        userinfo_claims_source=new_config.userinfo_claims_source,
        username_claim=username_claim_mapping,
        claim_mapping=other_user_mappings,
        groups_claim=group_settings.get("claim_mapping", []),
        sync_groups=group_settings.get("sync", True),
        sync_groups_glob_pattern=group_settings.get("sync_pattern", "*"),
        make_users_staff=group_settings.get("make_users_staff", False),
        superuser_group_names=group_settings.get("superuser_group_names", []),
    )

    groups = [
        Group.objects.get_or_create(name=group_name)[0]
        for group_name in group_settings.get("default_groups", [])
    ]

    old_config.default_groups.set(groups)
    old_config.save()


def move_data_forward(apps, schema_editor):
    OIDCClient = apps.get_model("mozilla_django_oidc_db", "OIDCClient")
    OIDCProvider = apps.get_model("mozilla_django_oidc_db", "OIDCProvider")
    OpenIDConnectConfig = apps.get_model(
        "mozilla_django_oidc_db", "OpenIDConnectConfig"
    )

    # Only one solo model should be present
    old_config = OpenIDConnectConfig.objects.first()
    if not old_config:
        return

    oidc_provider = OIDCProvider.objects.create(
        identifier=OIDC_ADMIN_PROVIDER_CONFIG_IDENTIFIER,
        oidc_op_discovery_endpoint=(old_config.oidc_op_discovery_endpoint),
        oidc_op_jwks_endpoint=old_config.oidc_op_jwks_endpoint,
        oidc_op_authorization_endpoint=(old_config.oidc_op_authorization_endpoint),
        oidc_op_token_endpoint=old_config.oidc_op_token_endpoint,
        oidc_op_user_endpoint=old_config.oidc_op_user_endpoint,
        oidc_op_logout_endpoint=old_config.oidc_op_logout_endpoint,
        oidc_token_use_basic_auth=old_config.oidc_token_use_basic_auth,
        oidc_use_nonce=old_config.oidc_use_nonce,
        oidc_nonce_size=old_config.oidc_nonce_size,
        oidc_state_size=old_config.oidc_state_size,
    )

    OIDCClient.objects.create(
        identifier=OIDC_ADMIN_CONFIG_IDENTIFIER,
        enabled=old_config.enabled,
        oidc_provider=oidc_provider,
        oidc_rp_client_id=old_config.oidc_rp_client_id,
        oidc_rp_client_secret=old_config.oidc_rp_client_secret,
        oidc_rp_sign_algo=old_config.oidc_rp_sign_algo,
        oidc_rp_scopes_list=old_config.oidc_rp_scopes_list,
        oidc_rp_idp_sign_key=old_config.oidc_rp_idp_sign_key,
        oidc_keycloak_idp_hint=old_config.oidc_keycloak_idp_hint,
        userinfo_claims_source=old_config.userinfo_claims_source,
        options={
            "user_settings": {
                "claim_mappings": {
                    "username": old_config.username_claim,
                    **old_config.claim_mapping,
                },
                "username_case_sensitive": True,
            },
            "groups_settings": {
                "claim_mapping": old_config.groups_claim,
                "sync": old_config.sync_groups,
                "sync_pattern": old_config.sync_groups_glob_pattern,
                "default_groups": [
                    group.name for group in old_config.default_groups.all()
                ],
                "make_users_staff": old_config.make_users_staff,
                "superuser_group_names": old_config.superuser_group_names,
            },
        },
    )


class Migration(migrations.Migration):

    dependencies = [
        (
            "mozilla_django_oidc_db",
            "0006_oidcprovider_oidcclient",
        ),
    ]

    operations = [
        migrations.RunPython(move_data_forward, move_data_backwards),
    ]
