import dpath.util as dp
import json


def update(d, u, only_existing=True):
	for k, v in u.items():
		if isinstance(v, dict):
			if only_existing:
				r = update(d.get(k, {}), v)
				d[k] = r
			else:
				d[k] = v
		else:
			d[k] = u[k]
	return d


class User:
	def __init__(self, socket):
		self.socket = socket
		self.paths = []

	async def send(self, data):
		result = {}
		for path in self.paths:
			msg = dp.search(data, path)
			result.update(msg)
		if len(result) != 0:
			await self.socket.send(json.dumps(result))

	async def process(self, data):
		handled = True
		try:
			# Handle message subscription
			d = json.loads(data)
			if "+" in d:
				path = d['+']
				print("Received subscribe {}".format(path))
				self.path_add(path)
			elif "-" in d:
				path = d['-']
				print("Received unsubscribe {}".format(path))
				self.path_remove(path)
			elif "?" in d:
				print("Subscriptions: {}".format(self.paths))
				await self.socket.send(json.dumps({"?": self.paths}))
			else:
				handled = False
		except Exception as e:
			print(e)

		return handled

	def path_add(self, path):
		if path not in self.paths:
			self.paths.append(path)

	def path_remove(self, path):
		if path in self.paths:
			self.paths.remove(path)


class UserSet:
	def __init__(self):
		self.users = {}
		self.keys = None

	def __len__(self):
		return len(self.users)

	def clear(self):
		self.users = {}
		self.keys = None

	def add(self, key, user):
		self.users[key] = user

	def remove(self, key):
		self.users.pop(key, None)

	def get(self, key):
		return self.users[key]

	def __iter__(self):
		self.keys = iter(self.users.keys())
		return self

	def __next__(self):
		return self.users[next(self.keys)]


def check_fill(u):
	if u:
		print("Is occupied")
	else:
		print("Is empty")


if __name__ == '__main__':
	userset = UserSet()
	check_fill(userset)

	userset.add(1, "A")
	userset.add(2, "B")
	userset.add(3, "C")
	check_fill(userset)

	print("Len(userset) = {}".format(userset))
	for i in userset:
		print(i)

	userset.remove(3)
	for i in userset:
		print(i)

	userset.remove(2)
	for i in userset:
		print(i)

	userset.remove(1)
	for i in userset:
		print(i)

	a = {'Pot': {'Temp': 15.5}}
	b = {'Pot': {'Power': 2400}}

	print(a)
	print(b)

	a = update(a, b)

	print("a | b = {}".format(a))
