/*
 * Copyright (c) 2016 Audi AG
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.eclipse.mdm.mdfsorter;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.nio.ByteBuffer;

import org.eclipse.mdm.mdfsorter.mdf3.MDF3Util;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

public class MDF3UtilTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	@Test
	public void testGetBytesUInt32() {
		long l = Integer.MAX_VALUE * 2L + 1L;
		assertArrayEquals(MDF3Util.getBytesUInt32(l, false), new byte[] { -1, -1, -1, -1 });

		l = Integer.MAX_VALUE * 2L + 1L;
		assertArrayEquals(MDF3Util.getBytesUInt32(l, true), new byte[] { -1, -1, -1, -1 });
	}

	@Test
	public void testGetBytesUInt16() {
		int val = Short.MAX_VALUE + 1;
		assertArrayEquals(MDF3Util.getBytesUInt16(val, false), new byte[] { 0, -128 });
	}

	@Test
	public void ReadUINT32() {
		long val = Integer.MAX_VALUE + 1L;
		ByteBuffer buf1 = ByteBuffer.wrap(new byte[] { -128, 0, 0, 0 });
		assertEquals(val, MDF3Util.readUInt32(buf1, true));

		ByteBuffer buf2 = ByteBuffer.wrap(new byte[] { 0, 0, 0, -128 });
		assertEquals(val, MDF3Util.readUInt32(buf2, false));
	}

	@Test
	public void testGetBool() {
		assertArrayEquals(new byte[] { 1, 0 }, MDF3Util.getBytesBool(true, false));
	}

	@Test
	public void testParseBool() {
		ByteBuffer buf1 = ByteBuffer.wrap(new byte[] { 0, -1 });
		assertTrue(MDF3Util.readBool(buf1, false));
		buf1.rewind();
		assertTrue(MDF3Util.readBool(buf1, true));
		ByteBuffer buf2 = ByteBuffer.wrap(new byte[] { 0, 0 });
		assertFalse(MDF3Util.readBool(buf2, false));
	}

}
