class RegistryServer(object, IRegistryServer):
    def __init__(self, initial_value={}, refresh_callback=None, server_uri=None):
        if server_uri:
            self.server_uri = server_uri
        else:
            self.server_uri = SERVER_URI
        self.__registry = Registry(initial_value)
        self.__refresh_callback = refresh_callback
        self.socket = ServerSocket(self.server_uri)
        self._start_msg_thread()

    def _start_msg_thread(self):
        self.msg_thread = MsgThread(self, self.socket)
        self.msg_thread.daemon = True
        self.msg_thread.start()

    def _stop_msg_thread(self):
        self.msg_thread.exit()

    def get(self, key):
        return self.__registry.get(key)

    def set(self, key, value):
        resp = self.__registry.set(key, value)
        self.call_callback()
        return resp

    def remove(self, key):
        resp = self.__registry.remove(key)
        self.call_callback()
        return resp

    def commit(self, values):
        self.__registry.set_values(values)
        self.call_callback()


    def get_values(self):
        return self.__registry.get_values()

    def get_version(self):
        return self.__registry.get_version()

    def call_callback(self):
        if self.__refresh_callback:
            self.__refresh_callback(self)
class TestMsgThread:
    def setUp(self):
        self.registry_server_mock = Mock(spec=IRegistryServer)
        self.socket = Mock(spec=IServerSocket)
        self.m = MsgThread(self.registry_server_mock, self.socket)

    def test_run(self):
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.socket.recv.called

    def test_get(self):
        self.socket.recv.return_value = {'action':'get','key':'a'}
        self.registry_server_mock.get.return_value = 'value'
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.registry_server_mock.get.call_args == call('a')
        assert self.socket.send.call_args == call('value')

    def test_set(self):
        self.registry_server_mock.get_version.return_value = 1
        self.socket.recv.return_value = {
            'action':'set',
            'key':'a',
            'value':'value'
        }
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.registry_server_mock.set.call_args == call('a','value')
        assert self.socket.send.call_args == call(1)

    def test_remove(self):
        self.registry_server_mock.get_version.return_value = 1
        self.socket.recv.return_value = {
            'action':'remove',
            'key':'a'
        }
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.registry_server_mock.remove.call_args == call('a')
        assert self.socket.send.call_args == call(1)

    def test_commit(self):
        self.registry_server_mock.get_version.return_value = 1
        self.socket.recv.return_value = {
            'action':'commit',
            'data':{'a':'b','c':'d'}
        }
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.registry_server_mock.commit.call_args == call({'a':'b','c':'d'})
        assert self.socket.send.call_args == call(1)

    def test_get_values(self):
        self.socket.recv.return_value = {
            'action':'get_values'
        }
        self.m.start()
        time.sleep(WAIT_TIME)
        self.m.exit()
        assert self.registry_server_mock.get_values.called
        assert self.socket.send.called