1from __future__ import print_function
2
3
4class ObjectDB(object):
5
6    def __init__(self, db, validation):
7        self.db = db
8        self.validation = validation
9        self.observers = []
10        self.files = db.files
11
12    def validate_files(self):
13        for file in list(self.files):
14            if not self.validation.is_file_valid(file):
15                del self.files[file]
16                self._file_removed(file)
17
18    def validate_file(self, file):
19        if file not in self.files:
20            return
21        for key in list(self.files[file]):
22            if not self.validation.is_scope_valid(file, key):
23                del self.files[file][key]
24
25    def file_moved(self, file, newfile):
26        if file not in self.files:
27            return
28        self.files.rename(file, newfile)
29        self._file_removed(file)
30        self._file_added(newfile)
31
32    def get_files(self):
33        return self.files.keys()
34
35    def get_returned(self, path, key, args):
36        scope_info = self._get_scope_info(path, key, readonly=True)
37        result = scope_info.get_returned(args)
38        if self.validation.is_value_valid(result):
39            return result
40
41    def get_pername(self, path, key, name):
42        scope_info = self._get_scope_info(path, key, readonly=True)
43        result = scope_info.get_per_name(name)
44        if self.validation.is_value_valid(result):
45            return result
46
47    def get_callinfos(self, path, key):
48        scope_info = self._get_scope_info(path, key, readonly=True)
49        return scope_info.get_call_infos()
50
51    def add_callinfo(self, path, key, args, returned):
52        scope_info = self._get_scope_info(path, key, readonly=False)
53        old_returned = scope_info.get_returned(args)
54        if self.validation.is_more_valid(returned, old_returned):
55            scope_info.add_call(args, returned)
56
57    def add_pername(self, path, key, name, value):
58        scope_info = self._get_scope_info(path, key, readonly=False)
59        old_value = scope_info.get_per_name(name)
60        if self.validation.is_more_valid(value, old_value):
61            scope_info.save_per_name(name, value)
62
63    def add_file_list_observer(self, observer):
64        self.observers.append(observer)
65
66    def write(self):
67        self.db.write()
68
69    def _get_scope_info(self, path, key, readonly=True):
70        if path not in self.files:
71            if readonly:
72                return _NullScopeInfo()
73            self.files.create(path)
74            self._file_added(path)
75        if key not in self.files[path]:
76            if readonly:
77                return _NullScopeInfo()
78            self.files[path].create_scope(key)
79        result = self.files[path][key]
80        if isinstance(result, dict):
81            print(self.files, self.files[path], self.files[path][key])
82        return result
83
84    def _file_removed(self, path):
85        for observer in self.observers:
86            observer.removed(path)
87
88    def _file_added(self, path):
89        for observer in self.observers:
90            observer.added(path)
91
92    def __str__(self):
93        scope_count = 0
94        for file_dict in self.files.values():
95            scope_count += len(file_dict)
96        return 'ObjectDB holds %s file and %s scope infos' % \
97               (len(self.files), scope_count)
98
99
100class _NullScopeInfo(object):
101
102    def __init__(self, error_on_write=True):
103        self.error_on_write = error_on_write
104
105    def get_per_name(self, name):
106        pass
107
108    def save_per_name(self, name, value):
109        if self.error_on_write:
110            raise NotImplementedError()
111
112    def get_returned(self, parameters):
113        pass
114
115    def get_call_infos(self):
116        return []
117
118    def add_call(self, parameters, returned):
119        if self.error_on_write:
120            raise NotImplementedError()
121
122
123class FileInfo(dict):
124
125    def create_scope(self, key):
126        pass
127
128
129class FileDict(dict):
130
131    def create(self, key):
132        pass
133
134    def rename(self, key, new_key):
135        pass
136
137
138class ScopeInfo(object):
139
140    def get_per_name(self, name):
141        pass
142
143    def save_per_name(self, name, value):
144        pass
145
146    def get_returned(self, parameters):
147        pass
148
149    def get_call_infos(self):
150        pass
151
152    def add_call(self, parameters, returned):
153        pass
154
155
156class CallInfo(object):
157
158    def __init__(self, args, returned):
159        self.args = args
160        self.returned = returned
161
162    def get_parameters(self):
163        return self.args
164
165    def get_returned(self):
166        return self.returned
167
168
169class FileListObserver(object):
170
171    def added(self, path):
172        pass
173
174    def removed(self, path):
175        pass
176