package hsr.dsa.notay;

import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import hsr.dsa.blockchain.BlockChainClient;
import hsr.dsa.blockchain.exceptions.SmartContractException;

public class TestNotaryContract {
	private static BlockChainClient client;
	private static long start = System.currentTimeMillis();
	private static String recipient;
	private static byte[] hash;
	private static boolean accept;

	@BeforeAll
	public static void setup() throws Exception {
		client = new BlockChainClient("da665e783b22be86881559f72e0d287311b8b4b2ac29035fc71e65cc7441f85d", null);
		System.out.println("setup done: " + (System.currentTimeMillis() - start));
		System.out.println("remaining ethers: " + client.getBalance());

		MessageDigest digest = MessageDigest.getInstance("SHA-256");
		hash = digest.digest(("skdjfhalskdfjh").getBytes(StandardCharsets.UTF_8));
		recipient = "0xe0fF2684D1A990F3290Df1115FA50F7b754f29B4";
		accept = true;
	}

	@AfterAll
	public static void tearDown() throws Exception {
		client.close();
	}

	@Test
	public void testAUpload() throws SmartContractException {
		client.upload(hash, recipient);
	}

	@Test
	public void testBVerifyUpload() throws SmartContractException {
	  testAUpload();

		long time = client.verifyUpload(hash, recipient);
		assertTrue(time > 0);
		
		long time2 = client.verifyUpload(hash, recipient);
		assertEquals(time, time2);
	}

	@Test
	public void testCReceived() throws SmartContractException {
		testBVerifyUpload();

		client.received(hash);
	}

	@Test
	public void testDVerifyReceived() throws SmartContractException {
		testCReceived();

		long time = client.verifyRecived(hash, recipient);
		assertTrue(time > 0);
		
		long time2 = client.verifyRecived(hash, recipient);
		assertEquals(time, time2);
	}

	@Test
	public void testEAcknowledge() throws SmartContractException {
		testDVerifyReceived();

		client.acknowledge(hash, accept);
	}

	@Test
	public void testFVerifyAcknowledged() throws SmartContractException {
		testEAcknowledge();

		long time = client.verifyAcknowledged(hash, recipient);
		assertTrue(time > 0);
		
		long time2 = client.verifyAcknowledged(hash, recipient);
		assertEquals(time, time2);
	}

	@Test
	public void testGisAccepted() throws SmartContractException {
		testFVerifyAcknowledged();

		boolean acceptedState = client.isAccepted(hash, recipient);
		assertTrue(acceptedState);
	}
}
