from kagglesdk.kaggle_object import *
from typing import Optional

class ExchangeOAuthTokenRequest(KaggleObject):
  r"""
  Attributes:
    code (str)
      Temporary OAuth code that was generated by the backend based on OAuth
      parameters passed to the '/api/v1/oauth2/authorize' (StartOAuthFlowRequest)
      endpoint. This is also known as OAuth flow token. It is sent to the flow
      initiator as a query string parameter to their redirect_uri
      (https://dataverse.org?code=808f9afcabb3489a8b30353a8ae4dc4b)
    code_verifier (str)
      Original code_verifier (hash of code_challenge) for PKCE protection.
    grant_type (str)
      Must be set to 'authorization_code'.
  """

  def __init__(self):
    self._code = ""
    self._code_verifier = None
    self._grant_type = ""
    self._freeze()

  @property
  def code(self) -> str:
    r"""
    Temporary OAuth code that was generated by the backend based on OAuth
    parameters passed to the '/api/v1/oauth2/authorize' (StartOAuthFlowRequest)
    endpoint. This is also known as OAuth flow token. It is sent to the flow
    initiator as a query string parameter to their redirect_uri
    (https://dataverse.org?code=808f9afcabb3489a8b30353a8ae4dc4b)
    """
    return self._code

  @code.setter
  def code(self, code: str):
    if code is None:
      del self.code
      return
    if not isinstance(code, str):
      raise TypeError('code must be of type str')
    self._code = code

  @property
  def code_verifier(self) -> str:
    """Original code_verifier (hash of code_challenge) for PKCE protection."""
    return self._code_verifier or ""

  @code_verifier.setter
  def code_verifier(self, code_verifier: Optional[str]):
    if code_verifier is None:
      del self.code_verifier
      return
    if not isinstance(code_verifier, str):
      raise TypeError('code_verifier must be of type str')
    self._code_verifier = code_verifier

  @property
  def grant_type(self) -> str:
    """Must be set to 'authorization_code'."""
    return self._grant_type

  @grant_type.setter
  def grant_type(self, grant_type: str):
    if grant_type is None:
      del self.grant_type
      return
    if not isinstance(grant_type, str):
      raise TypeError('grant_type must be of type str')
    self._grant_type = grant_type

  def endpoint(self):
    path = '/api/v1/oauth2/token'
    return path.format_map(self.to_field_map(self))


  @staticmethod
  def method():
    return 'POST'

  @staticmethod
  def body_fields():
    return '*'


class ExchangeOAuthTokenResponse(KaggleObject):
  r"""
  Attributes:
    access_token (str)
      Short-lived access token.
    refresh_token (str)
      Long-lived refresh token that can be used to generate access tokens using
      the '/api/v1/access-tokens/generate' (GenerateAccessTokenRequest) endpoint.
    token_type (str)
      Type of the token. Set to 'Bearer'.
    expires_in (int)
      Lifetime of the access token in seconds.
    username (str)
      Username of the user who authorized this token.
  """

  def __init__(self):
    self._access_token = ""
    self._refresh_token = ""
    self._token_type = ""
    self._expires_in = 0
    self._username = ""
    self._freeze()

  @property
  def access_token(self) -> str:
    """Short-lived access token."""
    return self._access_token

  @access_token.setter
  def access_token(self, access_token: str):
    if access_token is None:
      del self.access_token
      return
    if not isinstance(access_token, str):
      raise TypeError('access_token must be of type str')
    self._access_token = access_token

  @property
  def refresh_token(self) -> str:
    r"""
    Long-lived refresh token that can be used to generate access tokens using
    the '/api/v1/access-tokens/generate' (GenerateAccessTokenRequest) endpoint.
    """
    return self._refresh_token

  @refresh_token.setter
  def refresh_token(self, refresh_token: str):
    if refresh_token is None:
      del self.refresh_token
      return
    if not isinstance(refresh_token, str):
      raise TypeError('refresh_token must be of type str')
    self._refresh_token = refresh_token

  @property
  def token_type(self) -> str:
    """Type of the token. Set to 'Bearer'."""
    return self._token_type

  @token_type.setter
  def token_type(self, token_type: str):
    if token_type is None:
      del self.token_type
      return
    if not isinstance(token_type, str):
      raise TypeError('token_type must be of type str')
    self._token_type = token_type

  @property
  def expires_in(self) -> int:
    """Lifetime of the access token in seconds."""
    return self._expires_in

  @expires_in.setter
  def expires_in(self, expires_in: int):
    if expires_in is None:
      del self.expires_in
      return
    if not isinstance(expires_in, int):
      raise TypeError('expires_in must be of type int')
    self._expires_in = expires_in

  @property
  def username(self) -> str:
    """Username of the user who authorized this token."""
    return self._username

  @username.setter
  def username(self, username: str):
    if username is None:
      del self.username
      return
    if not isinstance(username, str):
      raise TypeError('username must be of type str')
    self._username = username

  @property
  def accessToken(self):
    return self.access_token

  @property
  def refreshToken(self):
    return self.refresh_token

  @property
  def tokenType(self):
    return self.token_type

  @property
  def expiresIn(self):
    return self.expires_in


class IntrospectTokenRequest(KaggleObject):
  r"""
  Attributes:
    token (str)
      Token to introspect (access token or refresh token), returned in the
      response of '/api/v1/oauth2/token' (ExchangeOAuthToken) RPC.
  """

  def __init__(self):
    self._token = ""
    self._freeze()

  @property
  def token(self) -> str:
    r"""
    Token to introspect (access token or refresh token), returned in the
    response of '/api/v1/oauth2/token' (ExchangeOAuthToken) RPC.
    """
    return self._token

  @token.setter
  def token(self, token: str):
    if token is None:
      del self.token
      return
    if not isinstance(token, str):
      raise TypeError('token must be of type str')
    self._token = token

  def endpoint(self):
    path = '/api/v1/oauth2/introspect'
    return path.format_map(self.to_field_map(self))


  @staticmethod
  def method():
    return 'POST'

  @staticmethod
  def body_fields():
    return '*'


class IntrospectTokenResponse(KaggleObject):
  r"""
  Attributes:
    active (bool)
      Indicates if the token is active, i.e., not revoked nor expired.
    client_id (str)
      The client identifier for the OAuth 2.0 client that the token was issued
      to.
    username (str)
      Username of the user who authorized this token.
    user_id (int)
      Id of the user who authorized this token.
    scope (str)
      Space-separated list of scopes.
    exp (int)
      The unix timestamp indicating when this token will expire.
  """

  def __init__(self):
    self._active = False
    self._client_id = ""
    self._username = ""
    self._user_id = None
    self._scope = ""
    self._exp = None
    self._freeze()

  @property
  def active(self) -> bool:
    """Indicates if the token is active, i.e., not revoked nor expired."""
    return self._active

  @active.setter
  def active(self, active: bool):
    if active is None:
      del self.active
      return
    if not isinstance(active, bool):
      raise TypeError('active must be of type bool')
    self._active = active

  @property
  def client_id(self) -> str:
    r"""
    The client identifier for the OAuth 2.0 client that the token was issued
    to.
    """
    return self._client_id

  @client_id.setter
  def client_id(self, client_id: str):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def username(self) -> str:
    """Username of the user who authorized this token."""
    return self._username

  @username.setter
  def username(self, username: str):
    if username is None:
      del self.username
      return
    if not isinstance(username, str):
      raise TypeError('username must be of type str')
    self._username = username

  @property
  def user_id(self) -> int:
    """Id of the user who authorized this token."""
    return self._user_id or 0

  @user_id.setter
  def user_id(self, user_id: Optional[int]):
    if user_id is None:
      del self.user_id
      return
    if not isinstance(user_id, int):
      raise TypeError('user_id must be of type int')
    self._user_id = user_id

  @property
  def scope(self) -> str:
    """Space-separated list of scopes."""
    return self._scope

  @scope.setter
  def scope(self, scope: str):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def exp(self) -> int:
    """The unix timestamp indicating when this token will expire."""
    return self._exp or 0

  @exp.setter
  def exp(self, exp: Optional[int]):
    if exp is None:
      del self.exp
      return
    if not isinstance(exp, int):
      raise TypeError('exp must be of type int')
    self._exp = exp

  @property
  def clientId(self):
    return self.client_id

  @property
  def userId(self):
    return self.user_id


class StartOAuthFlowRequest(KaggleObject):
  r"""
  Attributes:
    client_id (str)
      Client id that is initiating this OAuth flow.
    redirect_uri (str)
      Url to redirect the user after the OAuth flow is complete. For example, if
      you specify https://dataverse.org/auth/kaggle, you will receive a request
      like
      https://dataverse.org/auth/kaggle?code=808f9afcabb3489a8b30353a8ae4dc4b.
      Note that this url must match the allowed urls defined for your OAuth
      client. Also it must be a loopback url for public clients.
    scope (str)
      Set of authorization scopes to restrict the generated tokens. Must be
      specified.
    state (str)
      Random string to protect against CSRF attacks.
    code_challenge (str)
      Hash of the random 'code_verifier' string generated by the caller. The
      client will later send the 'code_verifier' to the backend, which will
      verify its hash against this value (see the 'api/v1/oauth2/exchange'
      (ExchangeOAuthTokenRequest) endpoint). Required for public clients.
    code_challenge_method (str)
      Code challenge method used to hash the 'code_challenge' above. Must be set
      to 'S256', which means the SHA-256 hash of the 'code_verifier', Base64URL
      encoded. Required for public clients.
    response_type (str)
      Type of the OAuth flow completed response. Must be set to 'code', which
      means OAuth code will be sent instead of a refresh token.
    response_mode (str)
      Mode of the OAuth flow completed response. Must be set to 'query', which
      means response will be sent as query string parameters.
  """

  def __init__(self):
    self._client_id = ""
    self._redirect_uri = ""
    self._scope = ""
    self._state = ""
    self._code_challenge = None
    self._code_challenge_method = None
    self._response_type = ""
    self._response_mode = ""
    self._freeze()

  @property
  def client_id(self) -> str:
    """Client id that is initiating this OAuth flow."""
    return self._client_id

  @client_id.setter
  def client_id(self, client_id: str):
    if client_id is None:
      del self.client_id
      return
    if not isinstance(client_id, str):
      raise TypeError('client_id must be of type str')
    self._client_id = client_id

  @property
  def redirect_uri(self) -> str:
    r"""
    Url to redirect the user after the OAuth flow is complete. For example, if
    you specify https://dataverse.org/auth/kaggle, you will receive a request
    like
    https://dataverse.org/auth/kaggle?code=808f9afcabb3489a8b30353a8ae4dc4b.
    Note that this url must match the allowed urls defined for your OAuth
    client. Also it must be a loopback url for public clients.
    """
    return self._redirect_uri

  @redirect_uri.setter
  def redirect_uri(self, redirect_uri: str):
    if redirect_uri is None:
      del self.redirect_uri
      return
    if not isinstance(redirect_uri, str):
      raise TypeError('redirect_uri must be of type str')
    self._redirect_uri = redirect_uri

  @property
  def scope(self) -> str:
    r"""
    Set of authorization scopes to restrict the generated tokens. Must be
    specified.
    """
    return self._scope

  @scope.setter
  def scope(self, scope: str):
    if scope is None:
      del self.scope
      return
    if not isinstance(scope, str):
      raise TypeError('scope must be of type str')
    self._scope = scope

  @property
  def state(self) -> str:
    """Random string to protect against CSRF attacks."""
    return self._state

  @state.setter
  def state(self, state: str):
    if state is None:
      del self.state
      return
    if not isinstance(state, str):
      raise TypeError('state must be of type str')
    self._state = state

  @property
  def code_challenge(self) -> str:
    r"""
    Hash of the random 'code_verifier' string generated by the caller. The
    client will later send the 'code_verifier' to the backend, which will
    verify its hash against this value (see the 'api/v1/oauth2/exchange'
    (ExchangeOAuthTokenRequest) endpoint). Required for public clients.
    """
    return self._code_challenge or ""

  @code_challenge.setter
  def code_challenge(self, code_challenge: Optional[str]):
    if code_challenge is None:
      del self.code_challenge
      return
    if not isinstance(code_challenge, str):
      raise TypeError('code_challenge must be of type str')
    self._code_challenge = code_challenge

  @property
  def code_challenge_method(self) -> str:
    r"""
    Code challenge method used to hash the 'code_challenge' above. Must be set
    to 'S256', which means the SHA-256 hash of the 'code_verifier', Base64URL
    encoded. Required for public clients.
    """
    return self._code_challenge_method or ""

  @code_challenge_method.setter
  def code_challenge_method(self, code_challenge_method: Optional[str]):
    if code_challenge_method is None:
      del self.code_challenge_method
      return
    if not isinstance(code_challenge_method, str):
      raise TypeError('code_challenge_method must be of type str')
    self._code_challenge_method = code_challenge_method

  @property
  def response_type(self) -> str:
    r"""
    Type of the OAuth flow completed response. Must be set to 'code', which
    means OAuth code will be sent instead of a refresh token.
    """
    return self._response_type

  @response_type.setter
  def response_type(self, response_type: str):
    if response_type is None:
      del self.response_type
      return
    if not isinstance(response_type, str):
      raise TypeError('response_type must be of type str')
    self._response_type = response_type

  @property
  def response_mode(self) -> str:
    r"""
    Mode of the OAuth flow completed response. Must be set to 'query', which
    means response will be sent as query string parameters.
    """
    return self._response_mode

  @response_mode.setter
  def response_mode(self, response_mode: str):
    if response_mode is None:
      del self.response_mode
      return
    if not isinstance(response_mode, str):
      raise TypeError('response_mode must be of type str')
    self._response_mode = response_mode

  def endpoint(self):
    path = '/api/v1/oauth2/authorize'
    return path.format_map(self.to_field_map(self))


ExchangeOAuthTokenRequest._fields = [
  FieldMetadata("code", "code", "_code", str, "", PredefinedSerializer()),
  FieldMetadata("codeVerifier", "code_verifier", "_code_verifier", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("grantType", "grant_type", "_grant_type", str, "", PredefinedSerializer()),
]

ExchangeOAuthTokenResponse._fields = [
  FieldMetadata("accessToken", "access_token", "_access_token", str, "", PredefinedSerializer()),
  FieldMetadata("refreshToken", "refresh_token", "_refresh_token", str, "", PredefinedSerializer()),
  FieldMetadata("tokenType", "token_type", "_token_type", str, "", PredefinedSerializer()),
  FieldMetadata("expiresIn", "expires_in", "_expires_in", int, 0, PredefinedSerializer()),
  FieldMetadata("username", "username", "_username", str, "", PredefinedSerializer()),
]

IntrospectTokenRequest._fields = [
  FieldMetadata("token", "token", "_token", str, "", PredefinedSerializer()),
]

IntrospectTokenResponse._fields = [
  FieldMetadata("active", "active", "_active", bool, False, PredefinedSerializer()),
  FieldMetadata("clientId", "client_id", "_client_id", str, "", PredefinedSerializer()),
  FieldMetadata("username", "username", "_username", str, "", PredefinedSerializer()),
  FieldMetadata("userId", "user_id", "_user_id", int, None, PredefinedSerializer(), optional=True),
  FieldMetadata("scope", "scope", "_scope", str, "", PredefinedSerializer()),
  FieldMetadata("exp", "exp", "_exp", int, None, PredefinedSerializer(), optional=True),
]

StartOAuthFlowRequest._fields = [
  FieldMetadata("clientId", "client_id", "_client_id", str, "", PredefinedSerializer()),
  FieldMetadata("redirectUri", "redirect_uri", "_redirect_uri", str, "", PredefinedSerializer()),
  FieldMetadata("scope", "scope", "_scope", str, "", PredefinedSerializer()),
  FieldMetadata("state", "state", "_state", str, "", PredefinedSerializer()),
  FieldMetadata("codeChallenge", "code_challenge", "_code_challenge", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("codeChallengeMethod", "code_challenge_method", "_code_challenge_method", str, None, PredefinedSerializer(), optional=True),
  FieldMetadata("responseType", "response_type", "_response_type", str, "", PredefinedSerializer()),
  FieldMetadata("responseMode", "response_mode", "_response_mode", str, "", PredefinedSerializer()),
]

