package it.micegroup.voila2.cartridge.library.javaservice;

import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

import org.apache.log4j.Appender;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.LogManager;
import org.apache.log4j.WriterAppender;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

public class ConsoleUtils {

	private static final Logger LOGGER = Logger.getLogger(ConsoleUtils.class.getName());
	public static final String CONSOLE_NAME = "VoilaPlugin";
	public static MessageConsoleStream out = null;
	public static LogFormatter logFormatter = new LogFormatter();

	static {
		LOGGER.setUseParentHandlers(false);

		ConsoleHandler handler = new ConsoleHandler();
		Formatter formatter = new LogFormatter();

		handler.setFormatter(formatter);

		LOGGER.addHandler(handler);

	}

	public static MessageConsoleStream setupConsole(String name) throws PartInitException {

		if (name == null) {
			name = CONSOLE_NAME;
		}
		ConsolePlugin plugin = ConsolePlugin.getDefault();
		IConsoleManager conMan = plugin.getConsoleManager();
		IConsole[] existing = conMan.getConsoles();
		for (int i = 0; i < existing.length; i++) {
			if (name.equals(existing[i].getName())) {
				MessageConsoleStream out = prepareConsole((MessageConsole) existing[i]);
				return out;
			}
		}
		// no console found, so create a new one
		MessageConsole myConsole = new MessageConsole(name, null);
		conMan.addConsoles(new IConsole[] { myConsole });

		MessageConsoleStream out = prepareConsole(myConsole);
		return out;
	}

	public static MessageConsoleStream prepareConsole(MessageConsole console) {
		console.activate();
		MessageConsoleStream out = console.newMessageStream();
		out.setActivateOnWrite(true);

		Appender a1Appender = LogManager.getRootLogger().getAppender("VoilaConsole");

		// Layout layout = new PatternLayout(LOG4J_PATTERN);
		try {
			Appender appender = new WriterAppender(a1Appender.getLayout(), out);
			appender.setName("Current" + a1Appender.getName());

			LogManager.getRootLogger().addAppender(appender);

			// LogManager.getRootLogger().removeAppender(a1Appender);
			// LogManager.getRootLogger().setLevel(a1Level);
			((ConsoleAppender) a1Appender).setWriter(new java.io.PrintWriter(System.err));
		} catch (Exception e) {
			e.printStackTrace();// FIXME
		}
//		Enumeration<Logger> loggers = LogManager.getCurrentLoggers();
//		while (loggers.hasMoreElements()) { 
//			Logger logger = (Logger) loggers.nextElement();
//			out.println(logger.getName());
//		}

		return out;
	}

	/**
	 * This method must be used only from acceleo's template to log in console,
	 * otherwise use Logger for the specific Java's class
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param severity
	 * @param message
	 */
	public void consoleMessage(String message) {
		consoleMessage(Level.INFO.getName(), message);
	}

	/**
	 * This method must be used only from acceleo's template to log in console,
	 * otherwise use Logger for the specific Java's class
	 * 
	 * @author Vittorio Niespolo <vittorio.niespolo@micegroup.it>
	 * @param severity
	 * @param message
	 */
	public static void consoleMessage(String severity, String message) {
		try {
			out = setupConsole(null);
		} catch (PartInitException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		LogRecord logRecord = null;
		if (severity.equals("FATAL")) {
			logRecord = new LogRecord(Level.SEVERE, message);
		} else if (severity.equals("INFO")) {
			logRecord = new LogRecord(Level.INFO, message);
		} else if (severity.equals("ERROR")) {
			logRecord = new LogRecord(Level.SEVERE, message);
		} else if (severity.equals("WARNING")) {
			logRecord = new LogRecord(Level.WARNING, message);
		} else if (severity.equals("DEBUG")) {
			logRecord = new LogRecord(Level.FINER, message);
		} else {
			logRecord = new LogRecord(Level.INFO, message);
		}

		out.println(logFormatter.format(logRecord));

		logRecord.setMessage(logRecord.getMessage().concat("\n"));

		LOGGER.log(logRecord);
//		IN CASO VENGA USATO COME PLUGIN
//		Activator plugin = Activator.getDefault();
//		plugin.getLog().log(new Status(Status.WARNING, plugin.getBundle().getSymbolicName(), Status.OK, msg, null));
	}
}
