import os
import shutil
import hashlib
import multiprocessing
from unittest import TestCase

import config
from hashtree import HashTree
from client import Client, Connection as ClientConnection
from server import Miniserver


dataDir=os.path.join(config.directory,"src/tests/data")
filename=os.path.join(dataDir,"test.img")


def compareFiles(f1,f2):
	with open(f1,mode="rb") as f:
		h2=hashlib.sha256(f.read()).hexdigest()
	with open(f2,mode="rb") as f:
		h=hashlib.sha256(f.read()).hexdigest()
	return (h,h2)


class TestMorevna(TestCase):
	def setUp(self):
		src=os.path.join(dataDir,"test1.img")
		shutil.copyfile(src,filename)

	@classmethod
	def tearDownClass(cls):
		os.remove(filename)

	def test_build(self):
		treeFile=os.path.join(dataDir,"test.bin")
		refFile=os.path.join(dataDir,"test1.bin")

		tree=HashTree.fromFile(os.path.join(dataDir,"test1.img"))
		tree.save(treeFile)

		self.assertEqual(*compareFiles(refFile,treeFile))

		os.remove(treeFile)

	def test_push(self):
		ms=Miniserver(filename)
		p=multiprocessing.Process(target=ms.serve)
		p.start()

		for clientFile in ("test2.img","test3.img"):
			clientFile=os.path.join(dataDir,clientFile)
			c=Client(clientFile)
			with ClientConnection() as con:
				c.setConnection(con)
				blocksToTransfer=c.negotiate()
				c.sendData(blocksToTransfer)

			self.assertEqual(*compareFiles(clientFile,filename))

		p.terminate()
		p.join()

	def test_pull(self):
		serverFile=os.path.join(dataDir,"test3.img")
		ms=Miniserver(serverFile)
		p=multiprocessing.Process(target=ms.serve)
		p.start()

		c=Client(filename)
		with ClientConnection() as con:
			c.setConnection(con)
			blocksToTransfer=c.negotiate()
			c.pullData(blocksToTransfer)

		self.assertEqual(*compareFiles(serverFile,filename))

		p.terminate()
		p.join()