import datetime
from typing import Tuple, Optional

import jwt

from idcloud.environment import Environment


class Configuration(object):
    def __init__(
        self,
        environment: Environment,
        api_key: str,
        tenant_id: str,
        jti: str,
        aud: str,
        iss: str,
        jwt_key_file: str,
        roles: list,
        mtls: Optional[Tuple[str, str]] = None,
        timeout: int = 30,
        jwt_expiration: int = int((datetime.datetime.utcnow() + datetime.timedelta(minutes=15)).timestamp()),
        algorithm: str = 'RS256'
    ):
        self._environment = environment
        self._api_key = api_key
        self._tenant_id = tenant_id
        self._jti = jti
        self._aud = aud
        self._iss = iss
        self._jwt_key_file = jwt_key_file
        self._roles = roles
        self._algorithm = algorithm
        self._timeout = timeout
        self._jwt_expiration = jwt_expiration
        self._jwt = self._generate_jwt_token()
        self._mtls = mtls

    def _generate_jwt_token(self):
        key_file = open(self._jwt_key_file, 'r')
        key_content = key_file.read().encode()

        token = jwt.encode(
            payload={
                'tenantId': self._tenant_id,
                'jti': self._jti,
                'roles': self._roles,
                "iat": int((datetime.datetime.utcnow() + datetime.timedelta(hours=2)).timestamp()),
                'exp': int((datetime.datetime.utcnow() + datetime.timedelta(hours=2, minutes=15)).timestamp()),
                'aud': self._aud,
                'iss': self._iss,
                'sub': self._tenant_id,
            },
            key=key_content,
            algorithm=self._algorithm,
            headers={
                'alg': self._algorithm,
                'typ': 'JWT',
                'kid': self._tenant_id
            }
        )

        return token

    @property
    def environment(self) -> Environment:
        return self._environment

    @property
    def api_key(self) -> str:
        return self._api_key

    @property
    def tenant_id(self) -> str:
        return self._tenant_id

    @property
    def roles(self) -> list:
        return self._roles

    @property
    def jwt_key_file(self) -> str:
        return self._jwt_key_file

    @property
    def algorithm(self) -> str:
        return self._algorithm

    @property
    def timeout(self) -> int:
        return self._timeout

    def jwt_expiration(self) -> int:
        return self._jwt_expiration

    @property
    def jwt(self) -> str:
        return self._jwt

    @property
    def mtls(self) -> Optional[Tuple[str, str]]:
        return self._mtls

    def jwt_refresh(self):
        self._jwt = self._generate_jwt_token()
        return self._jwt
