package org.ourfilesystem.test.security;

/*
OurFileSystem is a peer2peer file sharing program.
Copyright (C) 2012  Robert Gass

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

import static org.junit.Assert.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

import org.junit.Test;
import org.ourfilesystem.db.Peer;
import org.ourfilesystem.db.Post;
import org.ourfilesystem.security.CryptoDataBaseImpl;
import org.ourfilesystem.security.KeySet;
import org.ourfilesystem.security.PublicKeySetSigned;

public class CryptoDataBaseImplTest {
	
	private File createRandomFile(long size) {
		try {
			Random r = new Random();
			byte b[] = new byte[1024];
			File f = File.createTempFile("random", "tmp");
			FileOutputStream fos = new FileOutputStream(f);
			for (int cnt = 0; cnt < size/1024; cnt++) {
				r.nextBytes(b);
				fos.write(b);
			}
			fos.close();
			return f;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@Test
	public void test() {
		CryptoDataBaseImpl c = new CryptoDataBaseImpl();
		KeySet keyset0 = c.generateNewKeys();
		KeySet keyset1 = c.generateNewKeys();
		
		PublicKeySetSigned pub0 = new PublicKeySetSigned();
		PublicKeySetSigned pub1 = new PublicKeySetSigned();
		
		pub0.setPublicEncryptionKey(keyset0.getPublicKeySet().getPublicEncryptionKey());
		pub0.setPublicSigningKey(keyset0.getPublicKeySet().getPublicSigningKey());
		
		pub1.setPublicEncryptionKey(keyset1.getPublicKeySet().getPublicEncryptionKey());
		pub1.setPublicSigningKey(keyset1.getPublicKeySet().getPublicSigningKey());
		
		Peer p0 = new Peer();
		p0.setLocation("bbasdrfrewr.blah");
		p0.setPeerKeysAndIdentity(pub0);
		p0.setUpdateCount(0);
		
		Peer p1 = new Peer();
		p1.setLocation("bbas2341ewr.blah");
		p1.setPeerKeysAndIdentity(pub1);
		p1.setUpdateCount(1);

		c.signPeer(p0, null, keyset1.getPrivateSigningKey());
		
		assertTrue(c.verifyPeer(p0.getPeerKeysAndIdentity(), keyset1.getPublicKeySet().getPublicSigningKey()));
		assertFalse(c.verifyPeer(p0.getPeerKeysAndIdentity(), keyset0.getPublicKeySet().getPublicSigningKey()));
		
		File tf0 = createRandomFile(4096);
		File tf1 = createRandomFile(4096);
		
		Object dig0 = c.digestFile(tf0);
		Object dig1 = c.digestFile(tf1);
		Object dig2 = c.digestFile(tf0);
		
		assertFalse(c.digEquals(dig0, dig1));
		assertTrue(c.digEquals(dig0, dig2));
		
		Post s0 = new Post();
		s0.setFileReferenceDigest(dig0);
		s0.setMessage(tf1);
		s0.setPosterHasFile(true);
		s0.setPostNumber(1);
		c.signPost(s0, p0.getPeerKeysAndIdentity().getSignature().getDigest(), keyset0.getPrivateSigningKey());
		
		s0.setPosterHasFile(false);
		assertFalse(c.verifyPost(s0, p0.getPeerKeysAndIdentity().getPublicSigningKey()));
		
		s0.setPosterHasFile(true);
		s0.setFileReferenceDigest(dig1);
		assertFalse(c.verifyPost(s0, p0.getPeerKeysAndIdentity().getPublicSigningKey()));

		s0.setFileReferenceDigest(dig0);
		s0.setMessage(tf0);
		assertFalse(c.verifyPost(s0, p0.getPeerKeysAndIdentity().getPublicSigningKey()));
		
		s0.setMessage(tf1);
		s0.setPostNumber(2);
		assertFalse(c.verifyPost(s0, p0.getPeerKeysAndIdentity().getPublicSigningKey()));

		s0.setPostNumber(1);
		assertTrue(c.verifyPost(s0, p0.getPeerKeysAndIdentity().getPublicSigningKey()));
		assertFalse(c.verifyPost(s0, p1.getPeerKeysAndIdentity().getPublicSigningKey()));
		
	}

}
