package BFTSmartBlockchain;
import java.io.ByteArrayOutputStream;
import java.io.Serializable;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.interfaces.ECPublicKey;

import org.apache.commons.codec.binary.Hex;

public class Transaction implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public byte[] content;
	public ECPublicKey senderPublicKey;
	public byte[] signature;
	
	public Transaction(byte[] content, ECPublicKey senderPublicKey) {
		this.content = content;
		this.senderPublicKey = senderPublicKey;
	}
	
	public Transaction Sign(PrivateKey key) {
		try {
			// Select a digital signature algorithm
			Signature ECDSA = Signature.getInstance("SHA1withECDSA");
			// Initialize it with the private key
			ECDSA.initSign(key);
			// Set the message bytes into the signature algorithm
			ECDSA.update(contentBytes());
			// And sign it, getting the signature
			signature = ECDSA.sign();
		} catch (Exception e) {}
		return this;
	}
	
	public boolean Verify() {
		try {
			// Select a digital signature algorithm
			Signature ECDSA = Signature.getInstance("SHA1withECDSA");
			// Initialize the ECDSA algorithm for verification
			ECDSA.initVerify(senderPublicKey);
			// Set the message bytes into the signature algorithm
			ECDSA.update(contentBytes());
			// And verify it
			return ECDSA.verify(signature);	
		} catch (Exception e) {
			return false;
		}
	}
	
	public byte[] contentBytes() {
		try {
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(content);
			stream.write(senderPublicKey.getEncoded());
			return stream.toByteArray(); 
		} catch (Exception e) {
			return null;
		}
	}
	
	public byte[] asByteArray() {
		try {
			ByteArrayOutputStream stream = new ByteArrayOutputStream();
			stream.write(content);
			stream.write(senderPublicKey.getEncoded());
			stream.write(signature);
			return stream.toByteArray(); 
		} catch (Exception e) {
			return null;
		}
	}
	
	public String toString() {
		return "Transaction \n From: " + Hex.encodeHexString(senderPublicKey.getEncoded()) + 
					"\n With signature: " + Hex.encodeHexString(signature) + 
					"\n And content: " + Hex.encodeHexString(content);
	}

}
