/*******************************************************************************
 * 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.jdi.internal;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class VerboseWriter {
	/** Length of verbose description. */
	public static final int VERBOSE_DESCRIPTION_LENGTH = 21;
	/** Number of hexadecimal verbose bytes per line. */
	public static final int VERBOSE_HEX_BYTES_PER_LINE = 16;
	/** Width of hex dump. */
	public static final int VERBOSE_HEX_WIDTH = 16 * 3 + 2;

	/**
	 * Number extra verbose lines. These are caused by hex dumps that span more
	 * than one line.
	 */
	int fExtraVerboseLines = 0;

	/** PrintWriter that is written to. */
	private PrintWriter fOutput;
	/** Buffer for output: one StringBuffer entry per line. */
	private List<StringBuffer> fLineBuffer;
	/** Position from where buffer is written to. */
	private int fPosition;
	/** True if the current line has not yet been written to. */
	private boolean fNewLine = true;

	/**
	 * Creates new VerboseWriter that writes to the given PrintWriter. Output is
	 * buffered and previous entries in the buffer can be rewritten.
	 */
	public VerboseWriter(PrintWriter out) {
		fOutput = out;
		fLineBuffer = new ArrayList<>();
		fPosition = 0;
		fLineBuffer.add(new StringBuffer());
	}

	/**
	 * Terminate the current line by writing the line separator string. If
	 * autoflush is set and there are extra vebose lines caused by printHex,
	 * these lines are also printed.
	 */
	public void println() {
		while (fExtraVerboseLines > 0) {
			fExtraVerboseLines--;
			markLn();
		}

		markLn();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, byte value) {
		printDescription(description);
		printHex(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, short value) {
		printDescription(description);
		printHex(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, int value) {
		printDescription(description);
		printHex(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, long value) {
		printDescription(description);
		printHex(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, byte value, Map<Integer, String> valueToString) {
		printDescription(description);
		printHex(value);
		printValue(value, valueToString);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, short value, Map<Integer, String> valueToString) {
		printDescription(description);
		printHex(value);
		printValue(value, valueToString);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, int value, Map<Integer, String> valueToString) {
		printDescription(description);
		printHex(value);
		printValue(value, valueToString);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, byte value, String[] bitNames) {
		printDescription(description);
		printHex(value);
		printValue(value, bitNames);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, short value, String[] bitNames) {
		printDescription(description);
		printHex(value);
		printValue(value, bitNames);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, int value, String[] bitNames) {
		printDescription(description);
		printHex(value);
		printValue(value, bitNames);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, String value) {
		printDescription(description);
		printHex(value);
		print(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, boolean value) {
		printDescription(description);
		printHex(value);
		print(Boolean.valueOf(value).toString());
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, char value) {
		printDescription(description);
		printHex(value);
		print(value);
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, double value) {
		printDescription(description);
		printHex(value);
		print(new Double(value).toString());
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, float value) {
		printDescription(description);
		printHex(value);
		print(new Float(value).toString());
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, byte[] value) {
		printDescription(description);
		printHex(value);
		println();
	}

	/**
	 * Prints string with right size.
	 */
	public void printWidth(String str, int width) {
		print(str);
		int spaces = width - str.length();
		if (spaces > 0) {
			for (int i = 0; i < spaces; i++) {
				print(' ');
			}
		}
	}

	/**
	 * Prints description string with right size plus its seperator spaces.
	 */
	public void printDescription(String str) {
		printWidth(str, VERBOSE_DESCRIPTION_LENGTH);
	}

	/**
	 * Prints hex substitution string with right size plus its seperator spaces.
	 */
	public void printHexSubstitution(String str) {
		// Note that bytes also start with a space.
		print(' ');
		printWidth(str, VERBOSE_HEX_WIDTH - 1);
	}

	/**
	 * Appends hex representation of given byte to an array.
	 */
	private static void appendHexByte(byte b, char[] buffer, int pos) {
		int count = 2;

		int abspos = 3 * pos;
		buffer[abspos] = ' ';
		do {
			int t = b & 15;
			if (t > 9) {
				t = t - 10 + 'a';
			} else {
				t += '0';
			}
			buffer[count-- + abspos] = (char) t;
			b >>>= 4;
		} while (count > 0);
	}

	/**
	 * Appends remaining spaces to hex dump.
	 */
	private static void appendHexSpaces(char[] buffer, int pos) {
		for (int i = 3 * pos; i <= VERBOSE_HEX_WIDTH - 3; i += 3) {
			buffer[i] = ' ';
			buffer[i + 1] = ' ';
			buffer[i + 2] = ' ';
		}

		// Two extra spaces as seperator
		buffer[VERBOSE_HEX_WIDTH - 1] = ' ';
		buffer[VERBOSE_HEX_WIDTH - 2] = ' ';
	}

	/**
	 * Prints hex representation of a byte.
	 */
	public void printHex(byte b) {
		char buffer[] = new char[VERBOSE_HEX_WIDTH];
		appendHexByte(b, buffer, 0);
		appendHexSpaces(buffer, 1);
		print(buffer);
	}

	/**
	 * Prints hex representation of an int.
	 */
	public void printHex(short s) {
		char buffer[] = new char[VERBOSE_HEX_WIDTH];
		for (int i = 1; i >= 0; i--)
			appendHexByte((byte) (s >>> i * 8), buffer, 1 - i);
		appendHexSpaces(buffer, 2);
		print(buffer);
	}

	/**
	 * Prints hex representation of an int.
	 */
	public void printHex(int integer) {
		char buffer[] = new char[VERBOSE_HEX_WIDTH];
		for (int i = 3; i >= 0; i--)
			appendHexByte((byte) (integer >>> i * 8), buffer, 3 - i);
		appendHexSpaces(buffer, 4);
		print(buffer);
	}

	/**
	 * Prints hex representation of a long.
	 */
	public void printHex(long l) {
		char buffer[] = new char[VERBOSE_HEX_WIDTH];
		for (int i = 7; i >= 0; i--)
			appendHexByte((byte) (l >>> i * 8), buffer, 7 - i);
		appendHexSpaces(buffer, 8);
		print(buffer);
	}

	/**
	 * Prints hex representation of a long.
	 * @param b the boolean
	 */
	public void printHex(boolean b) {
		printHexSubstitution("<boolean>"); //$NON-NLS-1$
	}

	/**
	 * Prints hex representation of a long.
	 * @param c the char
	 */
	public void printHex(char c) {
		printHexSubstitution("<char>"); //$NON-NLS-1$
	}

	/**
	 * Prints hex representation of a long.
	 * @param d the double
	 */
	public void printHex(double d) {
		printHexSubstitution("<double>"); //$NON-NLS-1$
	}

	/**
	 * Prints hex representation of a long.
	 * @param f the float
	 */
	public void printHex(float f) {
		printHexSubstitution("<float>"); //$NON-NLS-1$
	}

	/**
	 * Prints hex representation of a String.
	 * @param str the string
	 */
	public void printHex(String str) {
		printHexSubstitution("<string>"); //$NON-NLS-1$
	}

	/**
	 * Prints hex representation of a byte array. Note that this can span more
	 * than one line, but is considered to be part of one 'verbose line'.
	 * Therefore, a println after a printHex can result in more than one line
	 * being printed to the PrintWriter.
	 */
	public void printHex(byte[] bytes) {
		int startPosition = position();
		char linebuf[] = new char[VERBOSE_HEX_WIDTH];
		int extraLines = 0;
		int byteOnLine = 0;

		for (byte b : bytes) {
			if (byteOnLine == VERBOSE_HEX_BYTES_PER_LINE) {
				appendHexSpaces(linebuf, VERBOSE_HEX_BYTES_PER_LINE);
				if (extraLines++ > 0) {
					printDescription(""); //$NON-NLS-1$
				}
				print(linebuf);
				markLn();
				byteOnLine = 0;
			}
			appendHexByte(b, linebuf, byteOnLine++);
		}
		appendHexSpaces(linebuf, byteOnLine);
		if (extraLines > 0) {
			printDescription(""); //$NON-NLS-1$
		}

		fExtraVerboseLines += extraLines;
		print(linebuf);
		if (extraLines > 0) {
			gotoPosition(startPosition);
		}
	}

	/**
	 * Prints string representation of a value given a Map from values to
	 * strings.
	 */
	public void printValue(int value, Map<Integer, String> valueToString) {
		Integer val = new Integer(value);
		if (valueToString == null) {
			print(val.toString());
			return;
		}
		String result = valueToString.get(val);
		if (result == null) {
			print(val.toString() + JDIMessages.VerboseWriter___unknown_value__1);
		} else {
			print(result);
		}
	}

	/**
	 * Prints string representation of a value given a Vector with the names of
	 * the bits.
	 */
	public void printValue(byte value, String[] bitNames) {
		printValue(value & 0xff, bitNames);
	}

	/**
	 * Prints string representation of a value given a Vector with the names of
	 * the bits.
	 */
	public void printValue(short value, String[] bitNames) {
		printValue(value & 0xffff, bitNames);
	}

	/**
	 * Prints string representation of a value given a Vector with the names of
	 * the bits.
	 */
	public void printValue(int value, String[] bitNames) {
		Integer val = new Integer(value);
		if (bitNames == null) {
			print(val.toString());
			return;
		}

		boolean bitsSet = false;

		for (int i = 0; i < bitNames.length; i++) {
			// Test if bit is set in value.
			if ((1 << i & value) == 0) {
				continue;
			}

			// See if we have a desciption for the bit.
			String bitString = bitNames[i];
			if (bitString == null) {
				bitString = JDIMessages.VerboseWriter__unknown_bit__2;
			}

			if (!bitsSet) {
				print(bitString);
			} else {
				print(" & "); //$NON-NLS-1$
				print(bitString);
			}
			bitsSet = true;
		}

		if (!bitsSet) {
			print(JDIMessages.VerboseWriter__none__4);
		}
	}

	/**
	 * Checks if a new line is written to. If so, first erase any data on that
	 * line. Line is marked 'not new' after this command.
	 */
	private void checkForNewLine() {
		if (fNewLine) {
			(fLineBuffer.get(fPosition)).setLength(0);
			fNewLine = false;
		}
	}

	/**
	 * Print a String.
	 */
	public void print(String str) {
		checkForNewLine();
		(fLineBuffer.get(fPosition)).append(str);
	}

	/**
	 * Print a Character.
	 */
	public void print(char c) {
		checkForNewLine();
		(fLineBuffer.get(fPosition)).append(c);
	}

	/**
	 * Print array of Characters.
	 */
	public void print(char[] c) {
		checkForNewLine();
		(fLineBuffer.get(fPosition)).append(c);
	}

	/**
	 * Print a String and then terminate the line.
	 */
	public void println(String str) {
		print(str);
		println();
	}

	/**
	 * Flush buffer. If autoflush is off, this method is synchronized on the
	 * PrintWriter given in the constructor.
	 */
	public void flush() {
		synchronized (fOutput) {
			int bufSize = fLineBuffer.size();

			for (int i = 0; i < bufSize - 1; i++)
				fOutput.println(new String(fLineBuffer.get(i)));

			// The last line should be printed without an extra newline
			StringBuffer lastLine = fLineBuffer.get(bufSize - 1);
			if (lastLine.length() > 0)
				fOutput.print(new String(lastLine));

			fOutput.flush();
			fLineBuffer.clear();
			fPosition = 0;
			fLineBuffer.add(new StringBuffer());
		}
	}

	/**
	 * Go to the given position in the buffer. If the given position is smaller
	 * than the current position, subsequent print commands overwrite existing
	 * lines in the buffer. Else, new lines are added to the buffer.
	 */
	public void gotoPosition(int pos) {
		int delta = pos - fPosition;
		if (delta < 0) {
			fPosition = pos;
		} else {
			while (delta-- > 0)
				println();
		}
	}

	/**
	 * Prints given number of lines.
	 */
	public void printLines(int lines) {
		gotoPosition(fPosition + lines);
	}

	/**
	 * @return Returns current position in buffer.
	 */
	public int position() {
		return fPosition;
	}

	/**
	 * Terminate the current line by writing the line separator string, start at
	 * end of next line.
	 */
	public void markLn() {
		if (++fPosition == fLineBuffer.size()) {
			fLineBuffer.add(new StringBuffer());
		}

		fNewLine = true;
	}
}
