package org.bdware.sc.trace;

import java.io.PrintStream;
import java.util.Set;

import wrp.jdk.nashorn.internal.runtime.ScriptObject;
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;
import wrp.jdk.nashorn.internal.runtime.TraceMethod;

public class MethodInvokePrinter implements TraceMethod {

	PrintStream out;

	public void printObject(final Object arg) {
		if (arg instanceof ScriptObject) {
			final ScriptObject object = (ScriptObject) arg;

			boolean isFirst = true;
			final Set<Object> keySet = object.keySet();

			if (keySet.isEmpty()) {
				out.print(ScriptRuntime.safeToString(arg));
			} else {
				out.print("{ ");

				for (final Object key : keySet) {
					if (!isFirst) {
						out.print(", ");
					}

					out.print(key);
					out.print(":");

					final Object value = object.get(key);

					if (value instanceof ScriptObject) {
						out.print("...");
					} else {
						printObject(value);
					}

					isFirst = false;
				}

				out.print(" }");
			}
		} else {
			out.print(ScriptRuntime.safeToString(arg));
		}
	}

	public void tracePrint(final String tag, int pc, String methodName, final Object[] args, final Object result) {
		// boolean isVoid = type().returnType() == void.class;
		out.print(tag);
		out.print(methodName + "_" + pc + "(");
		if (args.length > 0) {
			printObject(args[0]);
			for (int i = 1; i < args.length; i++) {
				final Object arg = args[i];
				out.print(", ");

				if (!(arg instanceof ScriptObject && ((ScriptObject) arg).isScope())) {
					printObject(arg);
				} else {
					out.print("SCOPE");
				}
			}
		}
		out.print(")");
		if (tag.equals("EXIT  ")) {
			out.print(" --> ");
			printObject(result);
		}
		out.println();
	}

}
