"""
Models meta magic here
"""
from pso.fields import BaseField
from pso.query import BaseQuerySet


class ModelMetaClass(type):
    """
    Magic with fields
    """

    def __new__(meta, name, bases, attr_dict):
        attr_dict['_fields'] = []
        attr_dict['_stored_fields'] = []
        queryset_class = attr_dict.pop('__queryset_class__', BaseQuerySet)
        fields = []
        stored_fields = []

        for name, attr in attr_dict.items():
            if isinstance(attr, list) and len(attr) == 1 \
               and isinstance(attr[0], BaseField):
                # this allows to define models like
                # tage = list(TextField())
                attr = attr[0]
                attr_dict[name] = attr  # replace attr in object
                attr.multi_valued = True

            if isinstance(attr, BaseField):

                if not attr.name:
                    attr.name = name
                fields.append(name)
                if attr.store:
                    stored_fields.append(name)

            attr_dict['_fields'] = fields
            attr_dict['_stored_fields'] = stored_fields

        cls = super().__new__(meta, name, bases, attr_dict)

        # Bind QuerySet  # TODO check this
        setattr(cls, 'objects', queryset_class(cls))
        return cls


class BaseModel(metaclass=ModelMetaClass):
    """Base class for EngineSpecific models"""
    _fields = []
    _stored_fields = []
    _cache = {}

    def __init__(self, **kwargs):
        for key, arg in kwargs.items():
            if key in self._fields:
                setattr(self, key, arg)

    @classmethod
    def get_fields(cls):
        print(cls, cls._fields)
        return (getattr(cls, name) for name in cls._fields)

    def __iter__(self):
        """Only filed with data to emulate dict behavior"""
        for name in self._fields:
            yield name, self[name]

    def __repr__(self):
        return "<Model: {0.__class__.__name__}>".format(self)

    def __getitem__(self, key):
        return self._cache[key]

    def to_index(self):
        # return self._cache
        arr = {}
        for name in self._fields:
            field = getattr(self.__class__, name)
            if name == '_version_':
                continue
            if field.multi_valued:
                arr[name] = [field.to_index(val) for val in self._cache.get(name, [])]
            else:
                arr[name] = field.to_index(self._cache.get(name))
            return arr
      # def get_object

@@ -1025,36 +1025,32 @@
 (name)%0A%0A        
-    
 attr_dict%5B'_fiel
@@ -1063,20 +1063,16 @@
  fields%0A
-    
         
@@ -1114,16 +1114,49 @@
 d_fields
+%0A        attr_dict%5B'_cache'%5D = %7B%7D
 %0A%0A      
@@ -1420,65 +1420,8 @@
 s%22%22%22
-%0A    _fields = %5B%5D%0A    _stored_fields = %5B%5D%0A    _cache = %7B%7D
 %0A%0A  
@@ -1448,24 +1448,49 @@
  **kwargs):%0A
+        self._cache = %7B%7D%0A
         for 
@@ -1575,29 +1575,28 @@
   se
-tattr(self, key,
+lf._cache%5Bkey%5D =
  arg
-)
 %0A%0A  
@@ -2455,20 +2455,16 @@
 (name))%0A
-    
         

Fix wrong _cache