from typing import Dict, NewType, Generic, TypeVar, Type


Key = NewType('Key', str)
Lang = NewType('Lang', str)
Translation = NewType('Translation', str)
PLIndex = NewType('PLIndex', int)

KT = TypeVar('KT')
VT = TypeVar('VT')


class GenStorage(Generic[KT, VT]):
    def __init__(self, value_class: Type[VT]):
        self.dct: Dict[KT, VT] = {}
        self.value_class = value_class

    def __getitem__(self, item: KT) -> VT:
        if item not in self.dct:
            self.dct[item] = self.value_class()
        return self.dct[item]

    def __setitem__(self, key: KT, value: VT):
        self.dct[key] = value

    def __len__(self):
        return len(self.dct)


class Forms(GenStorage[PLIndex, Translation]):
    def __init__(self, value_class=Translation):
        super().__init__(value_class)


class Translations(GenStorage[Lang, Forms]):
    def __init__(self, value_class=Forms):
        super().__init__(value_class)


class Terms(GenStorage[Key, Translations]):
    def __init__(self, value_class=Translations):
        super().__init__(value_class)


