package de.ugoe.cs.util.console;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

import de.ugoe.cs.util.console.listener.IOutputListener;

/**
 * <p>
 * Implements an {@link IOutputListener} for the {@link Console} that logs all
 * outputs in a file. This can be used to "pipe" the output-stream of the
 * console into a file. The advantage of using this mechanism for piping is that
 * the file will only contain the output stream. No errors, no commands, etc.
 * </p>
 * 
 * @author Steffen Herbold
 * @version 1.0
 */
public class FileOutputListener implements IOutputListener {

	/**
	 * <p>
	 * Flag that ensures that only one log message is produced if the listener
	 * breaks, e.g., because of a full hard disk/quota.
	 * </p>
	 */
	boolean failureLogged = false;

	/**
	 * <p>
	 * Name of the output file.
	 * </p>
	 */
	String filename;

	/**
	 * <p>
	 * Writer for the output.
	 * </p>
	 */
	OutputStreamWriter writer = null;

	/**
	 * <p>
	 * Constructor. Creates a new FileOutputListener.
	 * </p>
	 * 
	 * @param filename
	 *            name and path of the file the listener writes to.
	 */
	public FileOutputListener(String filename) {
		this.filename = filename;

	}

	/**
	 * <p>
	 * Starts the listener by opening the file and registering it with the
	 * {@link Console}.
	 * </p>
	 */
	public void start() {
		try {
			FileOutputStream fos = new FileOutputStream(filename);
			writer = new OutputStreamWriter(fos, "UTF-8");
			Console.getInstance().registerOutputListener(this);
		} catch (IOException e) {
			Console.printerrln("Failed to start FileOutputListener for file "
					+ filename + ": " + e.getMessage());
		}
	}

	/**
	 * <p>
	 * Stops the listener by closing the file and removing itself from the
	 * {@link Console}.
	 * </p>
	 */
	public void stop() {
		Console.getInstance().removeOutputListener(this);
		if( writer!=null ) {
			try {
				writer.close();
				writer = null;
			} catch (IOException e) {
				Console.printerrln("Failed to close file " + filename + ": "
						+ e.getMessage());
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * de.ugoe.cs.util.console.listener.IOutputListener#outputMsg(java.lang.
	 * String)
	 */
	@Override
	public void outputMsg(String newMessage) {
		if( writer!=null ) {
			try {
				writer.write(newMessage);
			} catch (IOException e) {
				if (!failureLogged) {
					Console.printerrln("FileOutpustListener for file " + filename
							+ " broken: " + e.getMessage());
					failureLogged = true;
				}
			}
		}
	}

	/**
	 * <p>
	 * Returns the name of the log file used by this listener.
	 * </p>
	 * 
	 * @return name of the log file
	 */
	public String getFilename() {
		return filename;
	}

}
