"""فعال‌سازی direct grant و token exchange برای ورود موبایل (یک‌بار اجرا)."""
from __future__ import annotations

import os
import sys

import httpx

KEYCLOAK_URL = os.getenv("KEYCLOAK_SERVER_URL", "http://keycloak:8080")
REALM = os.getenv("KEYCLOAK_REALM", "superapp")
ADMIN_USER = os.getenv("KEYCLOAK_ADMIN", "admin")
ADMIN_PASSWORD = os.getenv("KEYCLOAK_ADMIN_PASSWORD", "admin")
CLIENT_ID = os.getenv("IDENTITY_KEYCLOAK_CLIENT_ID", "identity-access-service")
FRONTEND_CLIENT_ID = os.getenv("KEYCLOAK_FRONTEND_CLIENT_ID", "superapp-frontend")


def main() -> None:
    with httpx.Client(timeout=15.0) as client:
        token_resp = client.post(
            f"{KEYCLOAK_URL}/realms/master/protocol/openid-connect/token",
            data={
                "grant_type": "password",
                "client_id": "admin-cli",
                "username": ADMIN_USER,
                "password": ADMIN_PASSWORD,
            },
        )
        token_resp.raise_for_status()
        token = token_resp.json()["access_token"]
        headers = {"Authorization": f"Bearer {token}"}

        clients_resp = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients",
            params={"clientId": CLIENT_ID},
            headers=headers,
        )
        clients_resp.raise_for_status()
        clients = clients_resp.json()
        if not clients:
            print(f"Client not found: {CLIENT_ID}", file=sys.stderr)
            sys.exit(1)

        internal_id = clients[0]["id"]
        detail_resp = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients/{internal_id}",
            headers=headers,
        )
        detail_resp.raise_for_status()
        client_body = detail_resp.json()
        client_body["directAccessGrantsEnabled"] = True
        client_body["serviceAccountsEnabled"] = True
        attrs = client_body.get("attributes") or {}
        attrs["oauth2.token.exchange.grant.enabled"] = "true"
        client_body["attributes"] = attrs

        update_resp = client.put(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients/{internal_id}",
            json=client_body,
            headers=headers,
        )
        update_resp.raise_for_status()
        print(f"Updated {CLIENT_ID}: directAccessGrants + token exchange enabled.")

        sa_user_resp = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients/{internal_id}/service-account-user",
            headers=headers,
        )
        if sa_user_resp.status_code != 200:
            print("Service account user not found.", file=sys.stderr)
            return

        sa_user_id = sa_user_resp.json()["id"]
        rm_clients = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients",
            params={"clientId": "realm-management"},
            headers=headers,
        ).json()
        if not rm_clients:
            print("realm-management client not found.", file=sys.stderr)
            return

        rm_id = rm_clients[0]["id"]
        roles = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients/{rm_id}/roles",
            headers=headers,
        ).json()
        role_names = {"impersonation", "token-exchange"}
        for role in roles:
            if role.get("name") not in role_names:
                continue
            map_resp = client.post(
                f"{KEYCLOAK_URL}/admin/realms/{REALM}/users/{sa_user_id}/role-mappings/clients/{rm_id}",
                json=[role],
                headers=headers,
            )
            if map_resp.status_code in (204, 200):
                print(f"Granted {role['name']} to service account.")

        frontend_clients = client.get(
            f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients",
            params={"clientId": FRONTEND_CLIENT_ID},
            headers=headers,
        ).json()
        if frontend_clients:
            frontend_id = frontend_clients[0]["id"]
            perm_resp = client.get(
                f"{KEYCLOAK_URL}/admin/realms/{REALM}/clients/{internal_id}/management/permissions",
                headers=headers,
            )
            print(f"Frontend client id: {frontend_id} (token-exchange audience target).")
            if perm_resp.status_code == 200:
                print("Client permissions endpoint available.")


if __name__ == "__main__":
    main()
