import os
import shelve

cache_dir = "./cache"


def cache(cache_file_name: str):
    """Note: function must have a 'cache_key' kwarg."""
    shelve.open(os.path.join(cache_dir, cache_file_name), flag="c")

    def decorator(func):
        def f(*args, **kwargs):
            # Read cache key
            try:
                param = kwargs["cache_key"]
            except KeyError:
                raise ValueError(
                    "Cached methods MUST be called with a 'cache_key' KW arg."
                )
            if param == "":
                raise ValueError("Cache key must not be empty!")

            # Read parameter based on parameter string
            # param_string_parts: list[str] = parameter_definition
            # ob = args[0]
            # while len(param_string_parts) > 0:
            #     ob = ob.__getattribute__(param_string_parts.pop(0))
            #
            # assert isinstance(ob, str)
            # param: str = ob

            # Run function, saving by the
            with shelve.open(
                os.path.join(cache_dir, cache_file_name), flag="c"
            ) as shelf:
                if param not in shelf:
                    print(f"   ! miss ({param})")
                    shelf[param] = func(*args, **kwargs)
                    return shelf[param]
                else:
                    print(f"   ! hit ({param})")
                    return shelf[param]

        return f

    return decorator
