/*******************************************************************************
 * Copyright (c) 2000, 2012 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.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 StringBuilder entry per line. */
	private List<StringBuilder> 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 StringBuilder());
	}

	/**
	 * 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(Double.valueOf(value).toString());
		println();
	}

	/**
	 * Prints verbose line.
	 */
	public void println(String description, float value) {
		printDescription(description);
		printHex(value);
		print(Float.valueOf(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 = Integer.valueOf(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 = Integer.valueOf(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
			StringBuilder lastLine = fLineBuffer.get(bufSize - 1);
			if (lastLine.length() > 0)
				fOutput.print(new String(lastLine));

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

	/**
	 * 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 StringBuilder());
		}

		fNewLine = true;
	}
}
