"""
LenientNamedTuple Module
"""


class LenientNamedTuple:
    """
    Class which provides the NamedTuple functionality but allows initializing with unknown fields.
    The unknown fields will be ignored and mandatory fields are enforced
    """

    __initialized: bool = False
    unknown: dict = None

    def __init__(self, **kwargs):
        fields = list(self.__class__.__dict__["__annotations__"].keys())
        unknown = {}
        for k, v in kwargs.items():
            if k in fields:
                setattr(self, k, v)
                fields.remove(k)
            else:
                unknown[k] = v
        if len(fields) > 0:
            raise TypeError(f"missing {len(fields)} required arguments: {fields}")
        setattr(self, "unknown", unknown)
        self.__initialized = True
        super().__init__()

    def __setattr__(self, name, value):
        if self.__initialized:
            raise AttributeError("can't set attribute")
        super().__setattr__(name, value)

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        for k, v in self.__dict__.items():
            if k == "unknown":
                continue
            if other.__dict__[k] != v:
                return False

        return True
