package mixconfig.tools.dataretention.smartcard.commands;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.Arrays;

import mixconfig.tools.dataretention.smartcard.ApduConstants;
import mixconfig.tools.dataretention.smartcard.Helpers;

import org.junit.*;

public class StartDataTransmissionCommandTest extends AbstractCommandTest {

	private byte instruction = 0x45;
	private byte[] expectedHeader = { ApduConstants.CLA_ANON, ApduConstants.INSTRUCTION_START_DATA_TRANSMISSION, instruction, 0x00,
			StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand };
	private byte[] data;

	@Before
	public void initData() {
		data = new byte[255 * 2];
		for (int i = 0; i < data.length; i++) {
			data[i] = (byte) (i % 128);
		}
	}

	@Test
	public void apduIsBuiltCorrectly() {
		byte[] expected;

		this.command = new StartDataTransmissionCommand(instruction, data);
		expectedHeader[3] = StartDataTransmissionCommand.getNumberOfPackages(data.length);
		if (data.length < StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand) {
			expectedHeader[4] = (byte) data.length;
		}
		expected = Helpers.concatenate(expectedHeader, Arrays.copyOfRange(data, 0, command.arguments.length));
		checkAPDU(expected);

		data = new byte[] { 1 };
		this.command = new StartDataTransmissionCommand(instruction, data);
		expectedHeader[3] = 1;
		if (data.length < StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand) {
			expectedHeader[4] = (byte) data.length;
		}
		expected = Helpers.concatenate(expectedHeader, Arrays.copyOfRange(data, 0, command.arguments.length));
		checkAPDU(expected);

		data = new byte[] { };
		this.command = new StartDataTransmissionCommand(instruction, data);
		expectedHeader[3] = 1;
		expectedHeader =  Arrays.copyOfRange(expectedHeader, 0, 4);
		
		expected = Helpers.concatenate(expectedHeader, Arrays.copyOfRange(data, 0, command.arguments.length));
		checkAPDU(expected);
	}

	@Test
	public void testGetNumberOfPackages() {
		int i = 1;
		assertEquals(i, StartDataTransmissionCommand.getNumberOfPackages(0));
		assertEquals(i, StartDataTransmissionCommand.getNumberOfPackages(1));

		for (i = 2; i < 126; i++) {
			assertEquals(i, StartDataTransmissionCommand.getNumberOfPackages(i * StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand));
			assertEquals(i + 1, StartDataTransmissionCommand.getNumberOfPackages(i * StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand + 1));
		}

		i = 127;
		assertEquals(i, StartDataTransmissionCommand.getNumberOfPackages(i * StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand));
		try {
			assertEquals(i, StartDataTransmissionCommand.getNumberOfPackages(i * StartDataTransmissionCommand.bytesPerStartDataTransmisionCommand + 1));
			fail("No Exception was thrown.");
		} catch (IllegalArgumentException e) {
		}
	}
}