# 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

class Object:
    objects = Mock()
    def __init__(self, **kwargs):
        setattr(self, 'save', Mock())
        setattr(self, 'delete', Mock())
        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)


    def tologdict(self):
        return {}

class ONOSService(Object):
    leaf_model_name = 'ONOSService'

class ONOSApp(Object):
    leaf_model_name = 'ONOSApp'

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

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 {{ m.name }}(Object):
    {% for f in xproto_base_fields(m, proto.message_table) +  m.fields -%}
    {{ f.name }} = {{ xproto_first_non_empty([f.options.default, "None"]) }}
    {% endfor %}
    leaf_model_name = "{{ m.name }}"
{% endfor %}
