/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *     Patrik Suzzi <psuzzi@gmail.com> - Bug 507661
 *******************************************************************************/
package org.eclipse.ui.console;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.WorkbenchEncoding;
import org.eclipse.ui.internal.console.IOConsolePartitioner;
import org.eclipse.ui.internal.console.StreamDecoder;

/**
 * OutputStream used to write to an IOConsole.
 * <p>
 * Clients are not intended to instantiate this class directly, instead
 * use <code>IOConsole.newOutputStream()</code>.
 * </p>
 * <p>
 * Clients should avoid writing large amounts of output to this stream in the UI
 * thread. The console needs to process the output in the UI thread and if the client
 * hogs the UI thread writing output to the console, the console will not be able
 * to process the output.
 * </p>
 * @since 3.1
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
public class IOConsoleOutputStream extends OutputStream {
	/**
	 * Flag indicating whether this stream has been closed.
	 */
	private boolean closed = false;

	/**
	 * The console's document partitioner.
	 */
	private IOConsolePartitioner partitioner;

	/**
	 * The console this stream is attached to.
	 */
	private IOConsole console;

	/**
	 * Flag indicating that the console should be activated when data
	 * is written to this stream.
	 */
	private boolean activateOnWrite = false;

	/**
	 * The color used to decorate data written to this stream.
	 */
	private Color color;

	/**
	 * The font style used to decorate data written to this stream.
	 */
	private int fontStyle;

	private StreamDecoder decoder;

	private boolean prependCR;

	/**
	 * Constructs a new output stream on the given console.
	 *
	 * @param console I/O console
	 */
	IOConsoleOutputStream(IOConsole console, Charset charset) {
		this.decoder = new StreamDecoder(charset);
		this.console = console;
		this.partitioner = (IOConsolePartitioner) console.getPartitioner();
	}

	/**
	 * Returns the font style used to decorate data written to this stream.
	 *
	 * @return the font style used to decorate data written to this stream
	 */
	public int getFontStyle() {
		return fontStyle;
	}

	/**
	 * Sets the font style to be used to decorate data written to this stream.
	 *
	 * @param newFontStyle the font style to be used to decorate data written to this stream
	 */
	public void setFontStyle(int newFontStyle) {
		if (newFontStyle != fontStyle) {
			int old = fontStyle;
			fontStyle = newFontStyle;
			console.firePropertyChange(this, IConsoleConstants.P_FONT_STYLE, Integer.valueOf(old), Integer.valueOf(fontStyle));
		}
	}

	/**
	 * Returns whether the console this stream is writing to will be activated when this stream
	 * is written to.
	 *
	 * @return whether the console this stream is writing to will be activated when this stream
	 * is written to.
	 */
	public boolean isActivateOnWrite() {
		return activateOnWrite;
	}

	/**
	 * Sets whether to activate the console this stream is writing to when this stream
	 * is written to.
	 *
	 * @param activateOnWrite whether the console this stream is writing to will be activated when this stream
	 * is written to.
	 */
	public void setActivateOnWrite(boolean activateOnWrite) {
		this.activateOnWrite = activateOnWrite;
	}

	/**
	 * Sets the color of this stream. Use <code>null</code> to indicate
	 * the default color.
	 *
	 * @param newColor color of this stream, or <code>null</code>
	 */
	public void setColor(Color newColor) {
		Color old = color;
		if (old == null || !old.equals(newColor)) {
			color = newColor;
			console.firePropertyChange(this, IConsoleConstants.P_STREAM_COLOR, old, newColor);
		}
	}

	/**
	 * Returns the color of this stream, or <code>null</code>
	 * if default.
	 *
	 * @return the color of this stream, or <code>null</code>
	 */
	public Color getColor() {
		return color;
	}

	/**
	 * Returns true if the stream has been closed
	 * @return true is the stream has been closed, false otherwise.
	 */
	public synchronized boolean isClosed() {
		return closed;
	}

	/*
	 *  (non-Javadoc)
	 * @see java.io.OutputStream#close()
	 */
	@Override
	public synchronized void close() throws IOException {
		if(closed) {
			// Closeable#close() has no effect if already closed
			return;
		}
		StringBuilder builder = new StringBuilder();
		if (prependCR) { // force writing of last /r
			prependCR = false;
			builder.append('\r');
		}
		this.decoder.finish(builder);
		if (builder.length() > 0) {
			notifyParitioner(builder.toString());
		}
		console.streamClosed(this);
		closed = true;
		partitioner = null;
		decoder = null;
	}

	/*
	 *  (non-Javadoc)
	 * @see java.io.OutputStream#flush()
	 */
	@Override
	public void flush() throws IOException {
		if(closed) {
			throw new IOException("Output Stream is closed"); //$NON-NLS-1$
		}
	}

	/*
	 *  (non-Javadoc)
	 * @see java.io.OutputStream#write(byte[], int, int)
	 */
	@Override
	public synchronized void write(byte[] b, int off, int len) throws IOException {
		if (closed) {
			throw new IOException("Output Stream is closed"); //$NON-NLS-1$
		}
		StringBuilder builder = new StringBuilder();
		this.decoder.decode(builder, b, off, len);
		encodedWrite(builder.toString());
	}
	/*
	 *  (non-Javadoc)
	 * @see java.io.OutputStream#write(byte[])
	 */
	@Override
	public void write(byte[] b) throws IOException {
		write(b, 0, b.length);
	}
	/*
	 *  (non-Javadoc)
	 * @see java.io.OutputStream#write(int)
	 */
	@Override
	public void write(int b) throws IOException {
		write(new byte[] {(byte)b}, 0, 1);
	}

	/**
	 * Writes a character array to the attached console.
	 *
	 * @param buffer the char array to write to the attached console
	 * @throws IOException if the stream is closed
	 * @since 3.7
	 */
	public void write(char[] buffer) throws IOException {
		String str = new String(buffer);
		this.encodedWrite(str);
	}

	/**
	 * Writes a character array using specified offset and length to the
	 * attached console.
	 *
	 * @param buffer the char array to write to the attached console.
	 * @param off the initial offset
	 * @param len the length
	 * @throws IOException if the stream is closed
	 * @since 3.7
	 */
	public void write(char[] buffer, int off, int len) throws IOException {
		String str = new String(buffer, off, len);
		this.encodedWrite(str);
	}

	/**
	 * Writes a character sequence to the attached console.
	 *
	 * @param chars the string/characters to write to the attached console.
	 * @throws IOException if the stream is closed.
	 * @since 3.7
	 */
	public void write(CharSequence chars) throws IOException {
		String str = chars.toString();
		encodedWrite(str);
	}

	/**
	 * Writes a string to the attached console.
	 *
	 * @param str the string to write to the attached console
	 * @throws IOException if the stream is closed
	 */
	public void write(String str) throws IOException {
		encodedWrite(str);
	}

	private synchronized void encodedWrite(String encodedString) throws IOException {
		if(closed) {
			throw new IOException("Output Stream is closed"); //$NON-NLS-1$
		}
		String newencoding = encodedString;
		if (prependCR){
			newencoding = "\r" + newencoding; //$NON-NLS-1$
			prependCR=false;
		}
		if (newencoding.endsWith("\r")) { //$NON-NLS-1$
			prependCR = true;
			newencoding = new String(newencoding.substring(0, newencoding.length() - 1));
		}
		notifyParitioner(newencoding);
	}

	private void notifyParitioner(String encodedString) throws IOException {
		try {
			partitioner.streamAppended(this, encodedString);

			if (activateOnWrite) {
				console.activate();
			} else {
				ConsolePlugin.getDefault().getConsoleManager().warnOfContentChange(console);
			}
		} catch (IOException e) {
			if (!closed) {
				close();
			}
			throw e;
		}
	}

	/**
	 * Sets the character encoding used to interpret characters written to this steam.
	 *
	 * @param encoding encoding identifier
	 */
	public void setEncoding(String encoding) {
		String charsetName;
		if (encoding == null) {
			charsetName = WorkbenchEncoding.getWorkbenchDefaultEncoding();
		} else {
			charsetName = encoding;
		}
		Charset charset = Charset.forName(charsetName);
		try {
			this.setCharset(charset);
		} catch (IOException ioe) {
			// ignore exception while writing final characters
			// to avoid API break
		}
	}

	/**
	 * @param charset set the Charset for the attached console
	 * @throws IOException if the stream is closed
	 * @since 3.7
	 */
	public synchronized void setCharset(Charset charset) throws IOException {
		if (closed) {
			throw new IOException("Output Stream is closed"); //$NON-NLS-1$
		}
		StringBuilder builder = new StringBuilder();
		this.decoder.finish(builder);
		if (builder.length() > 0) {
			this.encodedWrite(builder.toString());
		}
		this.decoder = new StreamDecoder(charset);
	}

}
