/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation and others.
 * 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.debug.jdi.tests;

import java.util.List;
import java.util.ListIterator;

import com.sun.jdi.ArrayReference;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.DoubleValue;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.StringReference;
import com.sun.jdi.Value;

/**
 * Tests for JDI com.sun.jdi.ArrayReference
 * and JDWP Array command set.
 */
public class ArrayReferenceTest extends AbstractJDITest {

	private ArrayReference fArray;
	private ArrayReference fDoubleArray;

	/**
	 * Creates a new test.
	 */
	public ArrayReferenceTest() {
		super();
	}
	/**
	 * Init the fields that are used by this test only.
	 */
	@Override
	public void localSetUp() {
		// Get array references
		fArray = getObjectArrayReference();
		fDoubleArray = getNonEmptyDoubleArrayReference();
	}
	/**
	 * Run all tests and output to standard output.
	 * @param args
	 */
	public static void main(java.lang.String[] args) {
		new ArrayReferenceTest().runSuite(args);
	}
	/**
	 * Gets the name of the test case.
	 * @see junit.framework.TestCase#getName()
	 */
	@Override
	public String getName() {
		return "com.sun.jdi.ArrayReference";
	}
	/**
	 * Test JDI getValue(int), getValues(), getValues(int,int)
	 * setValue(Value,int), setValues(List) and setValues(int,List,int,int),
	 * and JDWP 'Array - Get values' and 'Array - Set values'.
	 */
	public void testJDIGetSetDoubleValue() {
		double one = 1.0;
		double pi = 3.1415926535;
		double twos = 2.2;
		double threes = 3.33;
		double cnt = 12345;
		double zero = 0.0;
		double delta = 0.0;

		DoubleValue dbl = (DoubleValue) fDoubleArray.getValue(0);
		assertEquals("testJDIGetSetDoubleValue.1", one, dbl.value(), delta);

		DoubleValue piValue = fVM.mirrorOf(pi);
		DoubleValue cntValue = fVM.mirrorOf(cnt);
		DoubleValue zeroValue = fVM.mirrorOf(zero);
		try {
			fDoubleArray.setValue(0, piValue);
		} catch (ClassNotLoadedException e) {
			assertTrue("testJDIGetSetDoubleValue.3.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("testJDIGetSetDoubleValue.3.2", false);
		}
		DoubleValue value = (DoubleValue) fDoubleArray.getValue(0);
		assertEquals("testJDIGetSetDoubleValue.4.1", value, piValue);
		assertEquals("testJDIGetSetDoubleValue.4.2", pi, value.value(), delta);

		// getValues()
		List<Value> values = fDoubleArray.getValues();
		double[] expected = new double[] { pi, twos, threes };
		ListIterator<Value> iterator = values.listIterator();
		while (iterator.hasNext()) {
			DoubleValue dv = (DoubleValue) iterator.next();
			boolean included = false;
			for (int i = 0; i < expected.length; i++) {
				if (dv.value() == expected[i]) {
					included = true;
					break;
				}
			}
			assertTrue("testJDIGetSetDoubleValue.5." + dv.value(), included);
		}

		// setValues(List)
		List<Value> newValues = values;
		newValues.set(1, cntValue);
		try {
			fDoubleArray.setValues(newValues);
		} catch (ClassNotLoadedException e) {
			assertTrue("testJDIGetSetDoubleValue.7.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("testJDIGetSetDoubleValue.7.2", false);
		}
		values = fDoubleArray.getValues();
		assertEquals("testJDIGetSetDoubleValue.8", values, newValues);

		// getValues(int,int)
		values = fDoubleArray.getValues(1, 2);
		expected = new double[] { cnt, threes };
		iterator = values.listIterator();
		while (iterator.hasNext()) {
			DoubleValue dv = (DoubleValue) iterator.next();
			boolean included = false;
			for (int i = 0; i < expected.length; i++) {
				if (dv.value() == expected[i]) {
					included = true;
					break;
				}
			}
			assertTrue("testJDIGetSetDoubleValue.9." + dv.value(), included);
		}

		// setValues(int,List,int,int)
		newValues = fDoubleArray.getValues(0, 2);
		newValues.set(0, zeroValue);
		try {
			fDoubleArray.setValues(0, newValues, 0, 2);
		} catch (ClassNotLoadedException e) {
			assertTrue("testJDIGetSetDoubleValue.11.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("testJDIGetSetDoubleValue.11.2", false);
		}
		values = fDoubleArray.getValues(0, 2);
		assertEquals("testJDIGetSetDoubleValue.12", values, newValues);
	}
	/**
	 * Test JDI getValue(int), getValues(), getValues(int,int)
	 * setValue(Value,int), setValues(List) and setValues(int,List,int,int),
	 * and JDWP 'Array - Get values' and 'Array - Set values'.
	 */
	public void testJDIGetSetValue() {
		// getValue(int)
		StringReference string = (StringReference) fArray.getValue(0);
		assertEquals("1", "foo", string.value());

		// setValue(int,Value)
		StringReference newValue = null;
		newValue = fVM.mirrorOf("biz");
		try {
			fArray.setValue(0, newValue);
		} catch (ClassNotLoadedException e) {
			assertTrue("2.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("2.2", false);
		}
		StringReference value = (StringReference) fArray.getValue(0);
		assertEquals("3", value, newValue);

		// getValues()
		List<Value> values = fArray.getValues();
		String[] expected = new String[] { "biz", "bar", "hop" };
		ListIterator<Value> iterator = values.listIterator();
		while (iterator.hasNext()) {
			StringReference ref = (StringReference) iterator.next();
			boolean included = false;
			for (int i = 0; i < expected.length; i++) {
				if (ref.value().equals(expected[i])) {
					included = true;
					break;
				}
			}
			assertTrue("4." + ref.value(), included);
		}

		// setValues(List)
		List<Value> newValues = values;
		newValue = fVM.mirrorOf("hip");
		newValues.set(1, newValue);
		try {
			fArray.setValues(newValues);
		} catch (ClassNotLoadedException e) {
			assertTrue("5.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("6.2", false);
		}
		values = fArray.getValues();
		assertEquals("7", values, newValues);

		// getValues(int,int)
		values = fArray.getValues(1, 2);
		expected = new String[] { "hip", "hop" };
		iterator = values.listIterator();
		while (iterator.hasNext()) {
			StringReference ref = (StringReference) iterator.next();
			boolean included = false;
			for (int i = 0; i < expected.length; i++) {
				if (ref.value().equals(expected[i])) {
					included = true;
					break;
				}
			}
			assertTrue("8." + ref.value(), included);
		}

		// setValues(int,List,int,int)
		newValues = fArray.getValues(0, 2);
		newValue = fVM.mirrorOf("rap");
		newValues.set(0, newValue);
		try {
			fArray.setValues(0, newValues, 0, 2);
		} catch (ClassNotLoadedException e) {
			assertTrue("9.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("9.2", false);
		}
		values = fArray.getValues(0, 2);
		assertEquals("10", values, newValues);

		// test null value
		newValues.set(0, null);
		try {
			fArray.setValues(0, newValues, 0, 2);
		} catch (ClassNotLoadedException e) {
			assertTrue("11.1", false);
		} catch (InvalidTypeException e) {
			assertTrue("11.2", false);
		}
		values = fArray.getValues(0, 2);
		assertEquals("12", values.get(0), null);
	}
	/**
	 * Test JDI length() and JDWP 'Array - Get length'.
	 */
	public void testJDILength() {
		int length = fArray.length();
		assertEquals("1", 3, length);
	}
}
