package org.ourfilesystem.test.postcodec;

/*
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.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import org.junit.Test;
import org.ourfilesystem.db.LocalPost;
import org.ourfilesystem.db.Post;
import org.ourfilesystem.postcodec.Codec;
import org.ourfilesystem.postcodec.PostDecoded;
import org.ourfilesystem.utilities.BBytes;

public class CodecTest {
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static boolean mapEquals(HashMap o0, HashMap o1) {
		if (o0.size() != o1.size()) return false;
		Iterator<Entry<String,Object>> i0 = o0.entrySet().iterator();
		while (i0.hasNext()) {
			Entry<String,Object> e = i0.next();
			Object v1 = o1.get(e.getKey());
			if (v1 == null) {
				if (e.getValue() != null) return false;
			}
			else {
				if (!v1.equals(e.getValue())) return false;
			}
		}
		return true;
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static boolean setEquals(Set s0, Set s1) {
		if (s0.size() != s1.size()) { return false; }
		if (!s0.containsAll(s1)) { return false; }
		return true;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static boolean stringMapEquals(Map m0, Map m1) {
		if (m0.size() != m1.size()) return false;
		Iterator<Entry<String,Set>> i = m0.entrySet().iterator();
		while (i.hasNext()) {
			Entry<String,Set> e = i.next();
			if (!setEquals((Set)e.getValue(), (Set)m1.get(e.getKey()))) return false;
		}
		return true;
	}
	
	@Test
	public void test() {
		Random r = new Random();
		
		Post p0 = new Post();
		LocalPost lp0 = new LocalPost();
		
		p0.setMessage(new File("testfile.dat"));
		lp0.setPost(p0);
		
		PostDecoded pd0 = new PostDecoded();
		pd0.setPost(lp0);
		pd0.setComment("This is a really cool comment.  Like, you're not even going to believe it.");
		pd0.getNumberValues().put("COOL_LEVEL", 213L);
		pd0.getNumberValues().put("AWESOME_NUM", 759L);
		pd0.pushStringValue("KEYWORD", "MAGICMAN");
		pd0.pushStringValue("KEYWORD", "WOW");
		pd0.pushStringValue("SOMETHINGELSE", "THERE");
		byte b0[] = new byte[1024];
		r.nextBytes(b0);
		BBytes bb0 = new BBytes(b0);
		pd0.pushReferenceValue("SOMEOTHERFILE", bb0);
		
		
		try {
			Codec.ecnode(pd0);
			PostDecoded pd1 = Codec.decode(pd0.getPost());
			
			assertTrue(stringMapEquals(pd0.getOtherReferences(), pd1.getOtherReferences()));
			assertTrue(mapEquals(pd0.getNumberValues(), pd1.getNumberValues()));
			assertTrue(stringMapEquals(pd0.getStringValues(), pd1.getStringValues()));
			
			assertEquals(pd0.getComment(), pd1.getComment());
			
		} catch (IOException e) {
			e.printStackTrace();
			fail();
		}
		
	}

}
