from dynamix_sdk import base, config
from dynamix_sdk.utils import F_DECORATOR


class BVSAuth(config.AuthenticatorProtocol):
    _config: config.BaseConfigWithDomain
    client_id: str
    client_secret: str
    password: str
    user_name: str

    def __init__(
        self,
        url: str,
        domain: str,
        client_id: str,
        client_secret: str,
        user_name: str,
        password: str,
        verify_ssl: bool = True,
        http503_attempts: int = 10,
        http503_attempts_interval: int = 5,
        result_extra_allow: bool = True,
        wrap_request_exceptions: bool = False,
        f_decorators: list[F_DECORATOR] | None = None,
    ):
        self._config = config.BaseConfigWithDomain(
            url=url,
            verify_ssl=verify_ssl,
            domain=domain,
            http503_attempts=http503_attempts,
            http503_attempts_interval=http503_attempts_interval,
            result_extra_allow=result_extra_allow,
            wrap_request_exceptions=wrap_request_exceptions,
            f_decorators=f_decorators,
        )

        self.client_id = client_id
        self.client_secret = client_secret
        self.user_name = user_name
        self.password = password

    @property
    def api(self):
        return BVSAPI(config=self._config)

    def get_jwt(self):
        return self.api.token(
            client_id=self.client_id,
            client_secret=self.client_secret,
            grant_type='password',
            password=self.password,
            response_type='token',
            scope='openid',
            user_name=self.user_name,
        ).access_token


class BVSTokenResult(base.BaseAPIResultModel):
    access_token: str


class BVSTokenProtocol(base.BasePostAPIFunctionProtocol):
    def token(
        self,
        *,
        client_id: str,
        client_secret: str,
        grant_type: str,
        password: str,
        response_type: str,
        scope: str,
        user_name: str,
    ) -> BVSTokenResult:
        ...


class BVSAPI(
    base.BaseAPI,
    BVSTokenProtocol,
    path_mapping_dict={
        'token': 'realms/[domain]/protocol/openid-connect/token',
    },
    name_mapping_dict={
        'access_token': 'access_token',
        'client_id': 'client_id',
        'client_secret': 'client_secret',
        'grant_type': 'grant_type',
        'password': 'password',
        'response_type': 'response_type',
        'scope': 'scope',
        'user_name': 'username',
        'user_name': 'username',
    },
    post_json=False,
):
    pass
