/*
 *   Copyright 2003-2004 The Apache Software Foundation.
// (c) Copyright IBM Corp. 2004, 2005 All Rights Reserved
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package org.apache.axis.tools.trace;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.axis.tools.common.*;

/**
 * A Buffered write that also contains the methods to add in in trace
 * TODO: Add in &this and threadid into each trace record
 */
class Tracer extends BufferedWriter {
	private Signature signature = null;
	private final static String SIGNATURE = "  /* AUTOINSERTED TRACE */";
	private Headers headers;
	private String namespace = null;
	private String hashifdef = null;
	private String hashelse = null;
	private String hashendif = null;
	private String module = null;

	private static Hashtable typetable = new Hashtable();
	static {
		typetable.put("char", "CHAR");
		typetable.put("unsigned char", "CHAR");
		typetable.put("unsigned short", "USHORT");
		typetable.put("short", "SHORT");
		typetable.put("signed short", "SHORT");
		typetable.put("unsigned", "UINT");
		typetable.put("unsigned int", "UINT");
		typetable.put("int", "INT");
		typetable.put("signed int", "INT");
		typetable.put("signed", "INT");
		typetable.put("unsigned long", "ULONG");
		typetable.put("long", "LONG");
		typetable.put("signed long", "LONG");
		typetable.put("double", "DOUBLE");
		typetable.put("float", "FLOAT");
		typetable.put("bool", "BOOL");
		typetable.put("string", "STLSTRING");
		typetable.put("AxisString", "STLSTRING");
		typetable.put("AxisXMLString", "STLSTRING");
		typetable.put("xsd__string", "STRING");
	}

	private final static Set charSet =
		new HashSet(
			Arrays.asList(
				new Object[] { "char", "AxisChar", "AxisXMLChar", "XML_Ch" }));

	/**
	 * @param writer a writer to the output file.
	 */
	Tracer(Writer writer, int depth, Headers headers) throws IOException {
		super(writer);
		this.headers = headers;
		namespace = Configuration.getConfigured("namespace");
		if (null != namespace)
			namespace += "::";
		else
			namespace = "";
		
		hashifdef = Configuration.getConfigured("ifdef");
		if (null != hashifdef) {
			hashifdef = "#ifdef " + hashifdef + "\n";
			hashelse = "#else\n";
			hashendif = "#endif\n";
		} else {
			hashifdef = "";
			hashelse = "";
			hashendif = "";
		}

		module = Configuration.getConfigured("module");
		if (null != module)
			module += "::";
		else
			module = ""; // C-style function

		String include = Configuration.getConfigured("include");
		String includefile = "";
		if (null == include) {
			String prefix = "";
			if (depth > 1)
				for (int i = 1; i < depth; i++)
					prefix += "../";
			includefile = "\"" + prefix + "common/AxisTrace.h\"";

		} else {
			includefile = include;
		}

		String prefix = "";
		if (depth > 1)
			for (int i = 1; i < depth; i++)
				prefix += "../";

		String line =
			hashifdef
				+ "/* TRACE ADDED BY THE TRACE INSTRUMENTOR TOOL */\n"
				+ "#include "
				+ includefile
				+ "\n"
				+ hashendif;
		writeTrace(line);
		flush();
	}

	/**
	 * @param signature the signature of this method
	 * TODO: Can't tell the difference between static and non-static 
	 * methods so can't tell whether to pass this or not. If we pass
	 * this in a static method it won't compile. 
	 */
	void traceEntry(Signature signature) throws IOException {
		this.signature = signature;
		if (!signature.traceable())
			return;

		Parameter[] parms = signature.getParameters();
		int len = 0;
		if (null != parms) {
			if (parms[parms.length - 1].isDotDotDot())
				len = parms.length - 1;
			else
				len = parms.length;
		}

		String that = "NULL";
		if (headers.isInstanceMethod(signature))
			that = "this";

		String line =
			"\n"
				+ "\t"
				+ hashifdef
				+ "\t\tif ("
				+ namespace
				+ module
				+ "isTraceOn())\n"
				+ "\t\t\t"
				+ namespace
				+ module
				+ "traceEntry("
				+ getClassName()
				+ ", \""
				+ signature.getMethodName()
				+ "\", "
				+ that
				+ ", "
				+ len;
		for (int i = 0; null != parms && i < parms.length; i++)
			line += getTypeParms(parms[i]);
		line += ");\t" + SIGNATURE + "\n";
		line += "\t" + hashendif;
		writeTrace(line);
		flush();
	}

	void traceExit(int returnIndex) throws Exception {
		if (!signature.traceable())
			return;

		// Check this method really should return void
		if (null != signature.getReturnType().getType())
			Utils.rude(
				"Expecting to return void from a method that returns a value: "
					+ signature.toString());

		String that = "NULL";
		if (headers.isInstanceMethod(signature))
			that = "this";

		// Enclose the printf/return in {} in case if/then doesn't have {}
		String line = "\t{\n";
		line += "\t\t" + hashifdef;
		line += "\t\t\tif (" + namespace + module + "isTraceOn())\n";
		line += "\t\t\t\t"
			+ namespace
			+ module
			+ "traceExit("
			+ getClassName()
			+ ", \""
			+ signature.getMethodName()
			+ "\", "
			+ that
			+ ", "
			+ returnIndex
			+ ");\t"
			+ SIGNATURE
			+ "\n";
		line += "\t\t" + hashendif;

		// now print out the return line itself
		line += "\t\treturn;\n";
		line += "\t}\n";
		writeTrace(line);
		flush();
	}

	/**
	 * Takes in the return statement and traces out the exit trace statement for it
	 * This method prints out the complete return line as well so the user
	 * does not need to print this out themselves. 
	 */
	void traceExit(String value, int returnIndex) throws Exception {
		if (!signature.traceable())
			return;

		// Check this method doesn't return void
		if (null == signature.getReturnType().getType())
			Utils.rude(
				"Expecting to return a value from a method that returns void: "
					+ signature.toString());

		String that = "NULL";
		if (headers.isInstanceMethod(signature))
			that = "this";

		// Enclose the printf/return in {} in case if/then doesn't have {}
		// Copy the return value into a local called traceRet in case the
		// return value has side-effects such as "return i++;" or "return func();"
		// This makes sure that we don't execute the return value twice.
		// Unfortunately if the return value is a class we will invoke 
		// a copy constructor. When initialising traceRet with value, put value
		// in brackets in case it contains an operator that might be invoked
		// after the assignment, like another assignment.
		String line = "\t{\n";
		line += "\t\t" + hashifdef;
		line += "\t\t\t"
			+ signature.getReturnType().getType()
			+ " traceRet = ("
			+ value
			+ ");\n";
		line += "\t\t\tif (" + namespace + module + "isTraceOn())\n";
		line += "\t\t\t\t"
			+ namespace
			+ module
			+ "traceExit("
			+ getClassName()
			+ ", \""
			+ signature.getMethodName()
			+ "\", "
			+ that
			+ ", "
			+ returnIndex
			+ getTypeParms(signature.getReturnType(), true)
			+ ");\t"
			+ SIGNATURE
			+ "\n";
		line += "\t\t\treturn traceRet;\n";
		line += "\t\t" + hashelse;
		if (hashelse.length() > 0)
			line += "\t\t\treturn " + value + ";\n";
		line += "\t\t" + hashendif;
		line += "\t}\n";
		writeTrace(line);
		flush();
	}

	void traceCatch(Parameter value, int catchIndex) throws Exception {
		if (!signature.traceable())
			return;

		String that = "NULL";
		if (headers.isInstanceMethod(signature))
			that = "this";

		String line =
			"\n"
				+ "\t"
				+ hashifdef
				+ "\t\tif ("
				+ namespace
				+ module
				+ "isTraceOn())\n"
				+ "\t\t\t"
				+ namespace
				+ module
				+ "traceCatch("
				+ getClassName()
				+ ", \""
				+ signature.getMethodName()
				+ "\", "
				+ that
				+ ", "
				+ catchIndex
				+ getTypeParms(value);
		line += ");\t" + SIGNATURE + "\n";
		line += "\t" + hashendif;
		writeTrace(line);
		flush();
	}

	/*
	 * This method is careful to get the line separators because other
	 * other methods have been careless assuming that the line separator
	 * is always only \n, whereas it maybe \r\n.
	 */
	public void writeTrace(String s) throws IOException {
		if (s.startsWith("\n") || s.startsWith("\r"))
			super.newLine();
		StringTokenizer st = new StringTokenizer(s, "\n\r");
		while (st.hasMoreTokens()) {
			super.write(st.nextToken());
			if (st.hasMoreTokens())
				super.newLine();
		}
		if (s.endsWith("\n") || s.endsWith("\r"))
			super.newLine();
		if (Options.verbose())
			System.out.print(s);
	}

	// TODO cope with STL strings
	// TODO cope with pointers to primitives
	// TODO cope with references
	private String getTypeParms(Parameter p) { return getTypeParms(p,false); }
	private String getTypeParms(Parameter p, boolean isRetType) {
		// copes with catch (...)
		if ("...".equals(p.getType()))
			return " ";

		String parms = ",\n\t\t\t\t\tTRACETYPE_";
		String name = p.getName();
		if (isRetType)
			name = "traceRet";
		else if (null == name) {
			// A parameter without a name can't be traced
			parms += "ANONYMOUS, 0, NULL";
			return parms;
		}
		name = "((void*)&" + name + ")";

		String type = p.getTypeWithoutConst();
		if (null == type || 0 == type.length()) {
			parms += "UNKNOWN, 0, NULL";
		} else if (typetable.keySet().contains(type)) {
			parms += (String) typetable.get(type) + ", 0, " + name;
		} else if (type.endsWith("*")) {
			String contents = type.substring(0, type.length() - 1);
			if (charSet.contains(contents)) {
				parms += "STRING, 0, " + name;
			} else if ("void".equals(contents)) {
				// We just don't know what this void* is pointing at 
				// so that best we can do is to print out the first byte.
				parms += "POINTER, 1, " + name;
			} else {
				parms += "POINTER, sizeof(" + contents + "), " + name;
			}
		} else if (type.endsWith("&")) {
			String contents = type.substring(0, type.length() - 1);
			if (typetable.keySet().contains(contents)) {
				parms += (String) typetable.get(contents) + ", 0, " + name;
			} else if (contents.startsWith("Axis") && contents.endsWith("Exception")) {
				parms += "AXISEXCEPTION, sizeof(" + type + "), " + name;
			} else if (contents.equals("exception")) {
				parms += "EXCEPTION, sizeof(" + type + "), " + name;
			} else {
				parms += "DATA, sizeof(" + type + "), " + name;
			}
		} else if (type.startsWith("Axis") && type.endsWith("Exception")) {
			parms += "AXISEXCEPTION, sizeof(" + type + "), " + name;
		} else if (type.equals("exception")) {
			parms += "EXCEPTION, sizeof(" + type + "), " + name;
		} else {
			parms += "DATA, sizeof(" + type + "), " + name;
		}

		return parms;
	}

	private String getClassName() {
		String name;
		if (null != signature.getClassName()) {
			name = signature.getClassName();
			name = name.substring(0, name.indexOf("::"));
			name = "\"" + name + "\"";
		} else
			name = "NULL";
		return name;
	}
}
