# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from mock import Mock
import random

def mock_enumerator(items):
    e = lambda:None
    e.all = lambda:items
    return e

# A list of all mock object stores that have been created
AllMockObjectStores = []

class MockObjectList:
    item_list = None

    def __init__(self, initial=None):
        self.id_counter = 0
        if initial:
            self.item_list=initial
        elif self.item_list is None:
            self.item_list=[]

    def get_items(self):
        return self.item_list

    def count(self):
        return len(self.get_items())

    def first(self):
        return self.get_items()[0]

    def all(self):
        return self.get_items()

    def filter(self, **kwargs):
        items = self.get_items()
        for (k,v) in kwargs.items():
            items = [x for x in items if getattr(x,k) == v]
        return items

    def get(self, **kwargs):
        objs = self.filter(**kwargs)
        if not objs:
            raise IndexError("No objects matching %s" % str(kwargs))
        return objs[0]

class MockObjectStore(MockObjectList):
    def save(self, o):
        if (not hasattr(o,"id")) or (not o.id) or (o.id==98052):
            for item in self.get_items():
                if item.id >= self.id_counter:
                    self.id_counter = item.id + 1

            o.id = self.id_counter
            self.id_counter = self.id_counter + 1

        for item in self.get_items():
            if item.id == o.id:
                item = o
                break
        else:
            self.get_items().append(o)

class MockObject:
    objects = None
    id = None
    deleted = False

    def __init__(self, **kwargs):
        setattr(self, 'backend_code', 0)
        setattr(self, 'id', 98052)
        setattr(self, 'pk', random.randint(0, 1<<30))
        
        for (k,v) in kwargs.items():
            setattr(self,k,v)

    @property
    def self_content_type_id(self):
        return self.__class__.__name__

    @property
    def leaf_model(self):
        return self

    def save(self, update_fields=[], always_update_timestamp=False):
        if self.objects:
            self.objects.save(self)

    def delete(self):
        pass

    def tologdict(self):
        return {}

def get_MockObjectStore(x):
    store = globals()["Mock%sObjects" % x]()
    if not store in AllMockObjectStores:
        AllMockObjectStores.append(store)
    return store

class ModelAccessor:
    def check_db_connection_ok(self):
        return True

    def fetch_pending(self, model, deleted = False):
        num = random.randint(1, 5)
        object_list = []

        for i in range(num):
            if isinstance(model, list):
                model = model[0]

            try:
                obj = model()
            except:
                import pdb
                pdb.set_trace()

            obj.name = "Opinionated Berry %d"%i
            object_list.append(obj)
        
        return object_list

    def reset_all_object_stores(self):
        for store in AllMockObjectStores:
            store.items = []

    def get_model_class(self, classname):
        return globals()[classname]

model_accessor = ModelAccessor()

class ObjectSet(object):
    def __init__(self, objects):
        self.objects = objects

    def all(self):
        return self.objects
    
#####
# DO NOT MODIFY THE CLASSES BELOW. THEY ARE AUTOGENERATED.
# 

{% for m in proto.messages -%}
class Mock{{ m.name }}Objects(MockObjectStore): pass
class {{ m.name }}(MockObject):
    objects = get_MockObjectStore("{{ m.name }}")
    {% for f in xproto_base_fields(m, proto.message_table) +  m.fields -%}
    {{ f.name }} = {{ xproto_first_non_empty([f.options.default, "None"]) }}
    {% if f.link -%}{{ f.name }}_id = None{% endif %}
    {% endfor %}
    leaf_model_name = "{{ m.name }}"
{% endfor %}
