package aalgTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.junit.Assert;
import org.junit.Test;

import aalg.algebra.VariableNumberIo;

public class VariableNumberIoTest {

	private void testInt(final int num) throws IOException {
		final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		VariableNumberIo.writeInt(num, outStream);
		
		final ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
		final int result = VariableNumberIo.readInt(inStream);
		
		Assert.assertEquals(num, result);
	}
	
	@Test
	public void testReadWriteInt() throws IOException {
		final List<Integer> testedNums = new ArrayList<>();
		testedNums.add(0);
		testedNums.add(Integer.MAX_VALUE);
		
		for (VariableNumberIo.Range range: VariableNumberIo.getLongRanges()) {
			for (int i = -10; i <= 10; i++) {
				final int num = (int) range.getMax() + i;
				
				if (num >= 0)
					testedNums.add(num);
			}
		}
		
		for (int num: testedNums)
			testInt(num);
		
		final Random rnd = new Random(1234);
		
		for (int i = 0; i < 1000000; i++) {
			final int num = rnd.nextInt(Integer.MAX_VALUE);
			testInt(num);
		}
	}
	
	private void testLong(final long num) throws IOException {
		final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		VariableNumberIo.writeLong(num, outStream);
		
		final ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
		final long result = VariableNumberIo.readLong(inStream);
		
		Assert.assertEquals(num, result);
	}
	
	@Test
	public void testReadWriteLong() throws IOException {
		final List<Long> testedNums = new ArrayList<>();
		testedNums.add(0L);
		testedNums.add(Long.MAX_VALUE);
		
		for (VariableNumberIo.Range range: VariableNumberIo.getLongRanges()) {
			for (int i = -10; i <= 10; i++) {
				final long num = range.getMax() + i;
				
				if (num >= 0)
					testedNums.add(num);
			}
		}
		
		for (long num: testedNums)
			testLong(num);
		
		final Random rnd = new Random(1234);
		
		for (int i = 0; i < 1000000; i++) {
			final long num = rnd.nextLong() & Long.MAX_VALUE;
			testLong(num);
		}
	}

}
