/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.generic;

import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import static net.ranides.assira.junit.NewAssert.*;

/**
 *
 * @author msieron
 */


public class HashUtilsTest {
	
	public HashUtilsTest() {
	}

	@Test
	public void testMurmurHash3() {
		assertEquals(0x00000000, HashUtils.murmurHash3(0x0000000));
		assertEquals(0xAA4AA778, HashUtils.murmurHash3(0x00000020));
		assertEquals(0xB1A38591, HashUtils.murmurHash3(0x00003434));
		assertEquals(0xA23BAE67, HashUtils.murmurHash3(0x0000FFFF));
		assertEquals(0xF9CC0EA8, HashUtils.murmurHash3(0x7FFFFFFF));
		assertEquals(0x81F16F39, HashUtils.murmurHash3(0xFFFFFFFF));
		
		assertEquals(0x0000000000000000L, HashUtils.murmurHash3(0x00000000L));
		assertEquals(0xCC15890F1EEE9F7DL, HashUtils.murmurHash3(0x00000020L));
		assertEquals(0xADF941FD9F597C3AL, HashUtils.murmurHash3(0x00003434L));
		assertEquals(0x596F4BAF0B892560L, HashUtils.murmurHash3(0x0000FFFFL));
		assertEquals(0x8A662C1A93A26B91L, HashUtils.murmurHash3(0x7FFFFFFFL));
		assertEquals(0xCC71ECDA2AA8BCC6L, HashUtils.murmurHash3(0xFFFFFFFFL));
	}
	
	
	@Test
	public void testHash() {
		assertEquals("A".hashCode(), HashUtils.hash("A"));
		assertEquals(0, HashUtils.hash(null));
	}
	
	@Test
	public void testHashPair() {
		assertEquals(-1818165756, HashUtils.hashPair(0, 11));
		assertEquals(-1818165756, HashUtils.hashPair(null, 11));
		assertEquals(-1818165756, HashUtils.hashPair(11, 0));
		assertEquals(-1818165756, HashUtils.hashPair(11, null));
        
		assertEquals(1755047892, HashUtils.hashPair(99, 1037));
		assertEquals(1755047892, HashUtils.hashPair(1037, 99));
        
		assertEquals(-1672646182, HashUtils.hashPair(99, 0));
		assertEquals(-1672646182, HashUtils.hashPair(99, null));
	}
	
	
	@Test
	public void testHashIterable() {
		List<Integer> list1 = Arrays.asList(3,4,5);
		List<Integer> list2 = Arrays.asList(3,4,5,null);
		List<Integer> list3 = Arrays.asList(3,4,null, 5);
		
		assertEquals(345,  HashUtils.hashIterable(0, 10, list1));
		assertEquals(3450, HashUtils.hashIterable(0, 10, list2));
		assertEquals(3405, HashUtils.hashIterable(0, 10, list3));
	}
	
	@Test
	public void testHashIterable_Array() {
		Integer[] v1 = new Integer[]{1};
		Integer[] v2 = new Integer[]{2};
		Integer[] v3 = new Integer[]{3};
		List<Integer[]> list1 = Arrays.asList(v1,v2,v3);
		List<Integer[]> list2 = Arrays.asList(v1,v2,v3,null);
		List<Integer[]> list3 = Arrays.asList(v1,v2,null, v3);
		
		int h1 = Arrays.hashCode(v1);
		int h2 = Arrays.hashCode(v2);
		int h3 = Arrays.hashCode(v3);
	
		assertEquals( (((h1*100)+h2)*100)+h3, HashUtils.hashIterable(0, 100, list1));
		assertEquals( ((((h1*100)+h2)*100)+h3)*100, HashUtils.hashIterable(0, 100, list2));
		assertEquals( ((((h1*100)+h2)*100)+0)*100+h3, HashUtils.hashIterable(0, 100, list3));
	}
	
	@Test
	public void testHashIterable_Array_primitive() {
		int[] v1 = new int[]{1};
		int[] v2 = new int[]{2};
		int[] v3 = new int[]{3};
		List<int[]> list1 = Arrays.asList(v1,v2,v3);
		List<int[]> list2 = Arrays.asList(v1,v2,v3,null);
		List<int[]> list3 = Arrays.asList(v1,v2,null, v3);
		
		int h1 = Arrays.hashCode(v1);
		int h2 = Arrays.hashCode(v2);
		int h3 = Arrays.hashCode(v3);
	
		assertEquals( (((h1*100)+h2)*100)+h3, HashUtils.hashIterable(0, 100, list1));
		assertEquals( ((((h1*100)+h2)*100)+h3)*100, HashUtils.hashIterable(0, 100, list2));
		assertEquals( ((((h1*100)+h2)*100)+0)*100+h3, HashUtils.hashIterable(0, 100, list3));
	}
	
	@Test
	public void testDigest() {
		String h = "b7f783baed8297f0db917462184ff4f08e69c2d5e5f79a942600f9725f58ce1f29c18139bf80b06c0fff2bdd34738452ecf40c488c22a7e3d80cdf6f9c1c0d47";
		assertEquals(h, HashUtils.digest("Hello world"));
		
		assertNull(HashUtils.digest(null));
		assertNull(HashUtils.digest(""));
		
		assertThrows(UnsupportedOperationException.class, ()->{
			HashUtils.digest("Hello world", "invalid-algorithm");
		});
	}
	
}
