from typing import (
    Dict,
    Optional,
    Type,
)

from .codes import STEAM_ERROR_CODES


class SteamError(Exception):

    def __init__(self, error_code: int, error_msg: Optional[str] = None):
        self.error_code = error_code
        self.error_msg = error_msg

    def __str__(self) -> str:
        return str({
            'error': STEAM_ERROR_CODES.get(self.error_code, self.error_code),
            'msg': self.error_msg,
            'code': self.error_code,
        })


class UnknownSteamError(SteamError):
    ...


_CUSTOM_ERROR_EXCEPTIONS: Dict[int, Type[SteamError]] = {}


def custom_error_exception(errors: Dict[int, Type[SteamError]]) -> None:
    global _CUSTOM_ERROR_EXCEPTIONS
    if not isinstance(errors, dict):
        raise TypeError('The error argument should be dict')

    for _error, _exception in errors.items():
        if not isinstance(_error, int):
            raise TypeError('Error should be an integer')
        if not isinstance(_exception, type) or not issubclass(_exception, SteamError):
            raise TypeError('Exception should be inherited from SteamError')
        if _error not in STEAM_ERROR_CODES:
            raise TypeError(f'Unknown error code {_error}')
        _CUSTOM_ERROR_EXCEPTIONS[_error] = _exception
