package org.eclipse.debug.jdi.tests;

/**********************************************************************
Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
This file is made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
**********************************************************************/

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;

/**
 * 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.
	 */
	public void localSetUp() {
		// Get array references
		fArray = getObjectArrayReference();
		fDoubleArray = getNonEmptyDoubleArrayReference();
	}
	/**
	 * Run all tests and output to standard output.
	 */
	public static void main(java.lang.String[] args) {
		new ArrayReferenceTest().runSuite(args);
	}
	/**
	 * Gets the name of the test case.
	 */
	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 values = fDoubleArray.getValues();
		double[] expected = new double[] { pi, twos, threes };
		ListIterator 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 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 values = fArray.getValues();
		String[] expected = new String[] { "biz", "bar", "hop" };
		ListIterator 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 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);
	}
}
