/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.jdi.tests.program;


import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;

import org.eclipse.debug.jdi.tests.ClassTypeTest;

/**
 * Main class for target VM tests.
 * This class is intended to be run by the target VM.
 * It will use other classes in this package, and it will create and terminate
 * threads as a regular program would do.
 *
 * WARNING, WARNING:
 * Tests in org.eclipse.debug.jdi.tests assume the content of this class,
 * as well as its behavior. So if this class or one of the types in this
 * package is changed, the corresponding tests must also be changed.
 */
public class MainClass extends Date implements Runnable, Printable {

	private static byte[] byteArray = new byte[0];
	private static byte[][] byteDoubleArray = new byte[0][0];
	private static short[] shortArray = new short[0];
	private static short[][] shortDoubleArray = new short[0][0];
	private static int[] intArray = new int[0];
	private static int[][] intDoubleArray = new int[0][0];
	private static long[] longArray = new long[0];
	private static long[][] longDoubleArray = new long[0][0];
	private static double[] doubleArray = new double[0];
	private static double[][] doubleDoubleArray = new double[0][0];
	private static float[] floatArray = new float[0];
	private static float[][] floatDoubleArray = new float[0][0];
	private static char[] charArray = new char[0];
	private static char[][] charDoubleArray = new char[0][0];
	private static boolean[] booleanArray = new boolean[0];
	private static boolean[][] booleanDoubleArray = new boolean[0][0];

	private String string = "";
	private String[] stringArray = new String[0];
	private String[][] stringDoubleArray = new String[0][0];

	/**
	 * An integer value
	 */
	public static int fInt = 0;

	/**
	 * The instance of the <code>MainClass</code>
	 */
	public static MainClass fObject = new MainClass();

	/**
	 * A string initialized to 'hello world'
	 */
	public static String fString = "Hello World";

	/**
	 * A <code>Thread</code> object
	 */
	public static Thread fThread;

	/**
	 * A <code>Thread</code> object representing the main thread
	 */
	public static Thread fMainThread;

	/**
	 */
	public static String[] fArray = new String[] { "foo", "bar", "hop" };

	/**
	 * A pre-initialized array of doubles
	 */
	public static double[] fDoubleArray = new double[] { 1, 2.2, 3.33 };

	/**
	 * The name of an event type
	 */
	public static String fEventType = "";

	/**
	 * A boolean value initialized to <code>false</code>
	 */
	public boolean fBool = false;

	private char fChar = 'a';

	private String fString2 = "Hello";

	protected final String fString3 = "HEY";

	/**
	 * Constructor
	 */
	public MainClass() {}

	/**
	 * Constructor
	 * Used to test ClassType.newInstance
	 * @see ClassTypeTest
	 * @param i
	 * @param o1
	 * @param o2
	 */
	public MainClass(int i, Object o1, Object o2) {
	}

	/**
	 * For invocation tests
	 * @param x the integer
	 * @param o
	 * @return a string object representing the specified interger value
	 */
	private static String invoke1(int x, Object o) {
		if (o == null) {
			return (new Integer(x)).toString();
		} else {
			return "";
		}
	}
	/**
	 * For invocation tests
	 */
	private static void invoke2() {
		throw new IndexOutOfBoundsException();
	}

	/**
	 * For invocation tests
	 * @param str
	 * @param o
	 * @return an the integer value of the specified string
	 */
	private int invoke3(String str, Object o) {
		return Integer.parseInt(str);
	}
	/**
	 * For invocation tests
	 * @return nothing, only throws an exception
	 * @throws java.io.EOFException
	 */
	private long invoke4() throws java.io.EOFException {
		throw new java.io.EOFException();
	}
	/**
	 * For variables test
	 * @param l
	 */
	private void variablesTest(long l) {}

	/**
	 * Runs the test program
	 * @param args
	 */
	public static void main(java.lang.String[] args) {
		// Start the test program
		ThreadGroup group = new ThreadGroup("Test ThreadGroup");
		fThread = new Thread(group, fObject, "Test Thread");
		fThread.start();

		fMainThread = Thread.currentThread();

		// Prevent this thread from dying
		while (true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
	}
	/**
	 * @see org.eclipse.debug.jdi.tests.program.Printable#print(java.io.OutputStream)
	 */
	@Override
	public void print(OutputStream out) {
		String string = fInt++ +". " + fString;
		PrintWriter writer = new PrintWriter(out);
		writer.println(string);
		writer.flush();
	}

	/**
	 * Prints out a specified integer. This method is used in the force early return tests to ensure we
	 * can specify a different, type compatible return value
	 * @param out a stream to print out to
	 * @param num the number we want to print and return
	 * @return the specified number parameter, just pass it through
	 * @since 3.3
	 */
	public int printNumber(OutputStream out, int num) {
		String blah = "foo"+foo();
		PrintWriter writer = new PrintWriter(out);
		writer.println("The specified number is: "+num);
		writer.flush();
		return num;
	}

	/**
	 * Returns 20
	 *
	 * @return 20
	 */
	public int getInt() {
		int x = Math.max(20, 10);
		return x;
	}

	/**
	 * Returns true.
	 *
	 * @return true
	 */
	public boolean getBoolean() {
		boolean bool = Boolean.valueOf("true").booleanValue();
		return bool;
	}

	/**
	 * Returns 123L.
	 *
	 * @return 123
	 */
	public long getLong() {
		long l = Long.valueOf("123").longValue();
		return l;
	}

	/**
	 * dump out a string
	 * @return a String
	 * @since 3.3
	 */
	public String foo() {
		System.out.println("foobar");
		return "man";
	}

	/**
	 * make a sync'd method so we can stop in it to gather monitor information
	 * @since 3.3
	 */
	synchronized public void sync() {
		System.out.println("sync'd to the moon");
	}

	/**
	 * suspend on the first line of the method to get the argument values from the stackframe.
	 * used in testing the new 1.6VM capability to get argument values when no debugging info is available.
	 * @param str a string
	 * @param num a number
	 * @param obj an object
	 * @since 3.3
	 */
	public void argValues(String str, int num, Object obj) {
		System.out.println("get the arg values");
	}

	/**
	 * Prints to System.out and throws an exception to indicate readiness
	 */
	synchronized public void printAndSignal() {
		print(System.out);
		// Signal readiness by throwing an exception
		try {
			throw new NegativeArraySizeException();
		} catch (NegativeArraySizeException exc) {
		}
	}

	/**
	 * @see java.lang.Runnable#run()
	 */
	@Override
	public void run() {
		try {
			Thread t = Thread.currentThread();
			MainClass o = new OtherClass();
			// The front-end tests use the class load event to determine that the program has started

			if (CONSTANT == 2) {
				System.out.println("CONSTANT=2");
			}

			while (true) {
				printAndSignal();
				triggerEvent();
				useLocalVars(t, o);
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
				}
			}
		} finally {
			System.out.println("Running finally block in MainClass.run()");
		}
	}
	/**
	 *	Trigger an access watchpoint event for the front-end.
	 */
	private void triggerAccessWatchpointEvent() {
		if (fBool) {
			System.out.println("fBool is true");
		}
	}
	/**
	 *	Trigger a breakpoint event for the front-end.
	 */
	private void triggerBreakpointEvent() {
		System.out.println("Breakpoint");
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent() {
		new TestClass();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent1() {
		new TestClass1();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent2() {
		new TestClass2();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent3() {
		new TestClass3();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent4() {
		new TestClass4();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent5() {
		new TestClass5();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent6() {
		new TestClass6();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent7() {
		new TestClass7();
		new TestClazz8();
	}
	/**
	 *	Trigger a class prepare event for the front-end.
	 */
	private void triggerClassPrepareEvent8() {
		new TestClazz9();
		new TestClazz10();
	}
	/**
	 *	Trigger an event for the front-end.
	 */
	private void triggerEvent() {
		/* Ensure we do it only once */
		String eventType = fEventType;
		fEventType = "";

		/* Trigger event according to the field fEventType */
		if (eventType.isEmpty()) {
			return;
		} else if(eventType.equals("refclassload")) {
			new RefClass();
		}
		else if(eventType.equals("fooreturn")) {
			foo();
		}
		else if(eventType.equals("argvalues")) {
			argValues("teststr", 5, new Double(1.33));
		}
		else if(eventType.equals("forcereturn2")) {
			printNumber(System.out, 1);
		}
		else if(eventType.equals("forcereturn")) {
			print(System.out);
		}
		else if(eventType.equals("monitorinfo")) {
			sync();
		}
		else if(eventType.equals("refclass1load")) {
			new RefClass1();
		}
		else if(eventType.equals("refclass2load")) {
			new RefClass2();
		}
		else if(eventType.equals("refclass3load")) {
			new RefClass3();
		}
		else if(eventType.equals("refclass4load")) {
			new RefClass4();
		} else if (eventType.equals("getInt")) {
			getInt();
		} else if (eventType.equals("getBoolean")) {
			getBoolean();
		} else if (eventType.equals("getLong")) {
			getLong();
		} else if (eventType.equals("AccessWatchpointEvent")) {
			triggerAccessWatchpointEvent();
		} else if (eventType.equals("StaticAccessWatchpointEvent")) {
			triggerStaticAccessWatchpointEvent();
		} else if (eventType.equals("BreakpointEvent")) {
			triggerBreakpointEvent();
		} else if (eventType.equals("ClassPrepareEvent")) {
			triggerClassPrepareEvent();
		} else if (eventType.equals("ClassPrepareEvent1")) {
			triggerClassPrepareEvent1();
		} else if (eventType.equals("ClassPrepareEvent2")) {
			triggerClassPrepareEvent2();
		} else if (eventType.equals("ClassPrepareEvent3")) {
			triggerClassPrepareEvent3();
		} else if (eventType.equals("ClassPrepareEvent4")) {
			triggerClassPrepareEvent4();
		} else if (eventType.equals("ClassPrepareEvent5")) {
			triggerClassPrepareEvent5();
		} else if (eventType.equals("ClassPrepareEvent6")) {
			triggerClassPrepareEvent6();
		} else if (eventType.equals("ClassPrepareEvent7")) {
			triggerClassPrepareEvent7();
		} else if (eventType.equals("ClassPrepareEvent8")) {
			triggerClassPrepareEvent8();
		} else if (eventType.equals("ExceptionEvent")) {
			triggerExceptionEvent();
		} else if (eventType.equals("ModificationWatchpointEvent")) {
			triggerModificationWatchpointEvent();
		} else if (eventType.equals("StaticModificationWatchpointEvent")) {
			triggerStaticModificationWatchpointEvent();
		} else if (eventType.equals("ThreadStartEvent")) {
			triggerThreadStartEvent();
		} else if (eventType.equals("ThreadDeathEvent")) {
			triggerThreadDeathEvent();
		} else {
			System.out.println("Unknown event type: " + eventType);
		}
	}

	/**
	 *	Trigger an exception event for the front-end.
	 */
	private void triggerExceptionEvent() {
		Thread t = new Thread(new Runnable() {
			@Override
			public void run() {
				throw new Error();
			}
		}, "Test Exception Event");
		t.start();
	}
	/**
	 *	Trigger a modification watchpoint event for the front-end.
	 */
	private void triggerModificationWatchpointEvent() {
		fBool = true;
	}
	/**
	 * Trigger an access watchpoint event to a static field
	 * for the front-end.
	 */
	private void triggerStaticAccessWatchpointEvent() {
		if (fObject == null) {
			System.out.println("fObject is null");
		}
	}
	/**
	 * Trigger a modification watchpoint event of a static field
	 * for the front-end.
	 */
	private void triggerStaticModificationWatchpointEvent() {
		fString = "Hello Universe";
	}
	/**
	 *	Trigger a thread end event for the front-end.
	 */
	private void triggerThreadDeathEvent() {
		new Thread("Test Thread Death Event").start();
	}
	/**
	 *	Trigger a thread start event for the front-end.
	 */
	private void triggerThreadStartEvent() {
		new Thread("Test Thread Start Event").start();
	}
	private void useLocalVars(Thread t, MainClass o) {
		if (t == null) {
			System.out.println("t is null");
		}
		if (o == null) {
			System.out.println("o is null");
		}

	}
}
