"""
   Python SDK for OpenFGA

   API version: 0.1
   Website: https://openfga.dev
   Documentation: https://openfga.dev/docs
   Support: https://discord.gg/8naAwJfWN6
   License: [Apache-2.0](https://github.com/openfga/python-sdk/blob/main/LICENSE)

   NOTE: This file was auto generated by OpenAPI Generator (https://openapi-generator.tech). DO NOT EDIT.
"""

from dataclasses import dataclass
import typing
from urllib.parse import urlparse

from openfga_sdk.exceptions import ApiValueError


def none_or_empty(value):
    """
    Return true if value is either none or empty string
    """
    return value is None or value == ''


class CredentialConfiguration:
    """
    Configuration for SDK credential
    :param client_id: Client ID which will be matched with client_secret
    :param client_secret: Client secret which will be matched with client_id
    :param api_token: Bearer token to be sent for authentication
    :param api_audience: API audience used for OAuth2
    :param api_issuer: API issuer used for OAuth2
    """

    def __init__(
        self,
        client_id: typing.Optional[str] = None,
        client_secret: typing.Optional[str] = None,
        api_audience: typing.Optional[str] = None,
        api_issuer: typing.Optional[str] = None,
        api_token: typing.Optional[str] = None,
    ):
        self._client_id = client_id
        self._client_secret = client_secret
        self._api_audience = api_audience
        self._api_issuer = api_issuer
        self._api_token = api_token

    @property
    def client_id(self):
        """
        Return the client id configured
        """
        return self._client_id

    @client_id.setter
    def client_id(self, value):
        """
        Update the client id
        """
        self._client_id = value

    @property
    def client_secret(self):
        """
        Return the client secret configured
         """
        return self._client_secret

    @client_secret.setter
    def client_secret(self, value):
        """
        Update the client secret
        """
        self._client_secret = value

    @property
    def api_audience(self):
        """
        Return the api audience configured
        """
        return self._api_audience

    @api_audience.setter
    def api_audience(self, value):
        """
        Update the api audience
        """
        self._api_audience = value

    @property
    def api_issuer(self):
        """
        Return the api issuer configured
        """
        return self._api_issuer

    @api_issuer.setter
    def api_issuer(self, value):
        """
        Update the api issuer
        """
        self._api_issuer = value

    @property
    def api_token(self):
        """
        Return the api token configured
        """
        return self._api_token

    @api_token.setter
    def api_token(self, value):
        """
        Update the api token
        """
        self._api_token = value


class Credentials:
    """
    Manage the credential for the API Client
    :param method: Type of authentication. Possible value is 'none', 'api_token' and 'client_credentials'. Default as 'none'.
    :param configuration: Credential configuration of type CredentialConfiguration. Default as None.
    """

    def __init__(
        self,
        method: typing.Optional[str] = 'none',
        configuration: typing.Optional[CredentialConfiguration] = None,
    ):
        self._method = method
        self._configuration = configuration

    @property
    def method(self):
        """
        Return the method configured
        """
        return self._method

    @method.setter
    def method(self, value):
        """
        Update the method
        """
        self._method = value

    @property
    def configuration(self):
        """
        Return the configuration
        """
        return self._configuration

    @configuration.setter
    def configuration(self, value):
        """
        Update the configuration
        """
        self._configuration = value

    def validate_credentials_config(self):
        """
        Check whether credentials configuration is valid
        """
        if self.method != 'none' and self.method != 'api_token' and self.method != 'client_credentials':
            raise ApiValueError(
                'method `{}` must be either `none`, `api_token` or `client_credentials`'.format(self.method))
        if self.method == 'api_token' and (self.configuration is None or none_or_empty(self.configuration.api_token)):
            raise ApiValueError(
                'configuration `{}` api_token must be defined and non empty when method is api_token'.format(self.configuration))
        if self.method == 'client_credentials':
            if self.configuration is None or none_or_empty(self.configuration.client_id) or none_or_empty(self.configuration.client_secret) or none_or_empty(self.configuration.api_audience) or none_or_empty(self.configuration.api_issuer):
                raise ApiValueError(
                    'configuration `{}` requires client_id, client_secret, api_audience and api_issuer defined for client_credentials method.')
            # validate token issuer
            combined_url = 'https://' + self.configuration.api_issuer
            parsed_url = None
            try:
                parsed_url = urlparse(combined_url)
            except ValueError:
                raise ApiValueError('api_issuer `{}` is invalid'.format(
                    self.configuration.api_issuer))
            if (parsed_url.netloc == ''):
                raise ApiValueError('api_issuer `{}` is invalid'.format(
                    self.configuration.api_issuer))
