# -*- encoding: utf-8 -*-

from typing import Dict
from typing import Callable


class KeywordArgumentsRaiseIf(object):
    def __init__(self, **kwargs_changes: Dict[str, BaseException]):
        for oldkw in kwargs_changes.keys():
            assert isinstance(oldkw, str)
            assert isinstance(oldkw, BaseException) or issubclass(oldkw, BaseException)
        self.kwargs_changes = kwargs_changes

    def __call__(self, c):
        return KeywordArgumentsRaiserConfigured(c, False, **self.kwargs_changes)


class KeywordArgumentsRaiseIfNot(KeywordArgumentsRaiseIf):
    def __call__(self, c):
        return KeywordArgumentsRaiserConfigured(c, True, **self.kwargs_changes)


class KeywordArgumentsRaiserConfigured(object):  # Don't instantiate this class manually
    def __init__(self, clb: Callable, invert_logic: bool, **kwargs_changes: Dict[str, BaseException]):
        self.kwargs_changes = kwargs_changes
        self.filter = (lambda b: bool(b)) if invert_logic else (lambda b: not bool(b))
        self.callback = clb
    
    def __call__(self, *args, **kwargs):
        for kw, exc in self.kwargs_changes.items():
            if kw not in kwargs or self.filter(kwargs[kw]):
                raise exc
        return self.callback(*args, **kwargs)