/**
 * @author	STF 424_ITS_Test_Platform
 * @version    $URL:$
 *             $Id:$
 */
package org.etsi.its.codec.adapter.test;

import static org.junit.Assert.*;

import java.util.LinkedHashMap;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.etsi.its.codec.TestAdapterMessageTypeEnum;
import org.etsi.its.codec.adapter.AdapterControlCodecImpl;
import org.etsi.its.codec.adapter.IValue;
import org.etsi.its.codec.ttcn.LibItsGeoNetworking_TypesAndValues.GeoNetworkingTypesEnum;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * This class provides the test units for AdapterControlCodecImpl methods
 *
 */
public class AdapterControlCodecImplTest {

	/**
	 * Logger instance
	 */
	final static Logger _logger = Logger.getLogger("org.etsi.its");

	/**
	 * The instance of the class UpperTesterCodecImpl
	 */
	private static AdapterControlCodecImpl _iut;

	/**
	 * The list of the messages to be tested
	 */
	private static LinkedHashMap<String, byte[]> _messages;

	/**
	 * The list of the responses expected for each tested message
	 */
	private static LinkedHashMap<
		String,								// Ac primitive messages
		LinkedHashMap<
		TestAdapterMessageTypeEnum,		// Type identifier
			byte[]>							// Type value
	> _responses;

	/**
	 * @throws java.lang.Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		_logger.addHandler(new ConsoleHandler());
		_logger.setLevel(Level.ALL);
		_logger.getHandlers()[0].setLevel(Level.ALL);

		_iut = new AdapterControlCodecImpl();
		_messages = new LinkedHashMap<String, byte[]>();
		_responses = new LinkedHashMap<String, LinkedHashMap<TestAdapterMessageTypeEnum,byte[]>>();

		/*
		 * AcGnPrimitive
		 */
		// AcGetLongPosVector
		_messages.put("AcGetLongPosVector", new byte[] { (byte)0x01, (byte)0x00, (byte)0x0b, (byte)0x0b, (byte)0x00, (byte)0x08, (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef });
		_responses.put("AcGetLongPosVector", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("AcGetLongPosVector").put(TestAdapterMessageTypeEnum.AcGnPrimitive, new byte[] { (byte)0x0b, (byte)0x00, (byte)0x08, (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef });
		_responses.get("AcGetLongPosVector").put(TestAdapterMessageTypeEnum.AcGetLongPosVector, new byte[] { (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef });
		// AcStartBeaconing
		_messages.put("AcStartBeaconing", new byte[] { (byte)0x01, (byte)0x00, (byte)0x27, (byte)0x05, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef, (byte)0x00, (byte)0x01, (byte)0xe2, (byte)0x40, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0xf8, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xa3, (byte)0x00, (byte)0x37, (byte)0x26, (byte)0x94, (byte)0x02, (byte)0x0e, (byte)0x62, (byte)0x48 });
		_responses.put("AcStartBeaconing", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("AcStartBeaconing").put(TestAdapterMessageTypeEnum.AcGnPrimitive, new byte[] { (byte)0x05, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef, (byte)0x00, (byte)0x01, (byte)0xe2, (byte)0x40, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0xf8, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xa3, (byte)0x00, (byte)0x37, (byte)0x26, (byte)0x94, (byte)0x02, (byte)0x0e, (byte)0x62, (byte)0x48 });
		_responses.get("AcStartBeaconing").put(TestAdapterMessageTypeEnum.AcStartBeaconing, new byte[] { (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x94, (byte)0x21, (byte)0xa4, (byte)0xfe, (byte)0xde, (byte)0xca, (byte)0xbe, (byte)0xef, (byte)0x00, (byte)0x01, (byte)0xe2, (byte)0x40, (byte)0x00, (byte)0x00, (byte)0x12, (byte)0xf8, (byte)0x00, (byte)0x00, (byte)0x02, (byte)0xa3, (byte)0x00, (byte)0x37, (byte)0x26, (byte)0x94, (byte)0x02, (byte)0x0e, (byte)0x62, (byte)0x48 });
		// AcStartPassBeaconing
		_messages.put("AcStartPassBeaconing", new byte[] { (byte)0x01, (byte)0x00, (byte)0x27, (byte)0x07, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xb3, (byte)0xae, (byte)0x55, (byte)0x9a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 });
		_responses.put("AcStartPassBeaconing", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("AcStartPassBeaconing").put(TestAdapterMessageTypeEnum.AcGnPrimitive, new byte[] { (byte)0x07, (byte)0x00, (byte)0x24, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xb3, (byte)0xae, (byte)0x55, (byte)0x9a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 });
		_responses.get("AcStartPassBeaconing").put(TestAdapterMessageTypeEnum.AcStartPassBeaconing, new byte[] { (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x84, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0xb3, (byte)0xae, (byte)0x55, (byte)0x9a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 });
		// StopBeaconing
		_messages.put("StopBeaconing", new byte[] { (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x06, (byte)0x00, (byte)0x00 });
		_responses.put("StopBeaconing", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("StopBeaconing").put(TestAdapterMessageTypeEnum.AcGnPrimitive, new byte[] { (byte)0x06, (byte)0x00, (byte)0x00 });
		_responses.get("StopBeaconing").put(TestAdapterMessageTypeEnum.AcStopBeaconing, new byte[] { });
		// StopPassBeaconing
		_messages.put("StopPassBeaconing", new byte[] { (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x08, (byte)0x00, (byte)0x00 });
		_responses.put("StopPassBeaconing", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("StopPassBeaconing").put(TestAdapterMessageTypeEnum.AcGnPrimitive, new byte[] { (byte)0x08, (byte)0x00, (byte)0x00 });
		_responses.get("StopPassBeaconing").put(TestAdapterMessageTypeEnum.AcStopPassBeaconing, new byte[] { });
		/*
		 * AcGn6Primitive
		 */
		_messages.put("AcGn6Primitive", new byte[] { (byte)0x02, (byte)0x00, (byte)0x04, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03 });
		_responses.put("AcGn6Primitive", new LinkedHashMap<TestAdapterMessageTypeEnum, byte[]>());
		_responses.get("AcGn6Primitive").put(TestAdapterMessageTypeEnum.AcGn6Primitive, new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03 });
	}

	/**
	 * @throws java.lang.Exception
	 */
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		//empty
	}

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		//empty
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		//empty
	}

	/**
	 * Test method for {@link org.etsi.its.codec.adapter.AdapterControlCodecImpl#Decode(byte[])}.
	 */
	@Test
	public final void testDecode() {
		assertNull(_iut.Decode(null));

		assertNull(_iut.Decode(new byte[] { }));

		for (String message : _messages.keySet()) {
			IValue result = _iut.Decode(_messages.get(message));
			assertNotNull(String.format("#### Process message %s", message), result != null);
			for (TestAdapterMessageTypeEnum typeId : _responses.get(message).keySet()) {
				// Check type identifier
				assertNotNull(String.format("#### Process message type %s - %s", message, typeId.name()), result.getType(typeId));
				// Check type value
				assertArrayEquals(
					String.format("#### Process message value %s - %s", message, typeId.name()), 
					_responses.get(message).get(typeId), 
					(byte[])result.getType(typeId).getValue());
				assertNull(String.format("#### Process message type %s - %s", message, typeId.name()), result.getType(GeoNetworkingTypesEnum.e_100s));
			} // End of 'for' statement
		} // End of 'for' statement
	}
}
