# Copyright (c) 2022 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com
import sys
from collections.abc import Callable
from types import ModuleType
from typing import Generic, TypeVar, cast

T = TypeVar('T')


class _ModuleProperty(Generic[T]):
    def __init__(self, func: Callable[[], T]):
        self.func = func

    def resolve(self) -> T:
        return self.func()


class _ModulePropertyResolver(ModuleType):
    def __getattribute__(self, attr):
        val = super().__getattribute__(attr)
        return resolve(val)


def configure_resolver(module_name: str):
    sys.modules[module_name].__class__ = _ModulePropertyResolver


def create_property(func: Callable[[], T]) -> T:
    return cast(T, _ModuleProperty(func))


def resolve(val: T) -> T:
    if isinstance(val, _ModuleProperty):
        return val.resolve()
    return val
