/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.xtext.messagedsl.common;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService;
import org.eclipse.osbp.xtext.messagedsl.internal.BasicTranslator;
import org.eclipse.osbp.xtext.messagedsl.listener.MessageBroker;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.internal.databaseaccess.DatabaseCall;
import org.eclipse.persistence.queries.Call;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Message extends Exception {

	private static final long serialVersionUID = 8857086767567996406L;

	@SuppressWarnings("unused")
	private final Class<? extends IMessageCategory> fCategoryClass;
	private final AMessageGroup fMessageGroup;
	private final String fI18nKey;
	private String fLogFormat;
	private String fShowFormat;
	private Object[] fParams;
	private String fLogMessage;
	private String fShowMessage;
	private final Logger fLogger;
	private IDSLMetadataService dslMetadataService;
	private Locale locale;

	private static Map<Class<? extends AMessageGroup>, Logger> sLogger = new HashMap<Class<? extends AMessageGroup>, Logger>();

	private static Logger getLogger(AMessageGroup group) {
		return getLogger(group.getClass());
	}

	private static Logger getLogger(Class<? extends AMessageGroup> groupClass) {
		if (!sLogger.containsKey(groupClass)) {
			sLogger.put(groupClass, LoggerFactory.getLogger(groupClass));
		}
		return sLogger.get(groupClass);
	}

	public Message(IDSLMetadataService dslMetadataService, Locale locale, Class<? extends IMessageCategory> enumClass, AMessageGroup group,
			Object enumItem, String logFormat, String showFormat, Object... params) {
		this(dslMetadataService, locale, getLogger(group), enumClass, group, enumItem, logFormat, showFormat, params);
	}

	public Message(IDSLMetadataService dslMetadataService, Locale locale, Logger logger, Class<? extends IMessageCategory> enumClass,
			AMessageGroup group, Object enumItem, String logFormat, String showFormat, Object... params) {
		super();
		this.dslMetadataService = dslMetadataService;
		fLogger = logger;
		fCategoryClass = enumClass;
		fMessageGroup = group;
		fI18nKey = BasicTranslator.getTranslatorKey(enumClass, enumItem.toString());
		fLogFormat = logFormat;
		fShowFormat = showFormat;
		fParams = params;
		this.locale = locale;
	}

	private void prepareMessage() {
		if ((fLogMessage == null) || (fShowMessage == null)) {
			Map<String, String> replaces = new HashMap<>();
			String variable = null;
			if (fParams != null) {
				for (Object param : fParams) {
					if (variable != null) {
						try {
							if (param instanceof Boolean) {
								replaces.put("%%" + variable + "%%", param.toString());
							} else if (param instanceof Class<?>) {
								replaces.put("%%" + variable + ".canonicalName%%", ((Class<?>) param).getCanonicalName());
								replaces.put("%%" + variable + ".simpleName%%", ((Class<?>) param).getSimpleName());
							} else if (param instanceof Double) {
								replaces.put("%%" + variable + "%%", param.toString());
							} else if (param instanceof Exception) {
								if (param instanceof Throwable) {
									causedBy((Throwable) param);
								}
								replaces.put("%%" + variable + ".canonicalName%%", ((Exception) param).getClass().getCanonicalName());
								replaces.put("%%" + variable + ".simpleName%%", ((Exception) param).getClass().getSimpleName());
								replaces.put("%%" + variable + ".localizedMessage%%", ((Exception) param).getLocalizedMessage());
								replaces.put("%%" + variable + ".localizedDetailMessage%%", getLocalizedDetailMessage((Exception) param));
								replaces.put("%%" + variable + ".localizedSimpleDetailMessage%%",
										getLocalizedSimpleDetailMessage((Exception) param));
								replaces.put("%%" + variable + ".stackTrace%%", ExceptionUtils.getStackTrace((Exception) param));
							} else if (param instanceof Integer) {
								replaces.put("%%" + variable + "%%", param.toString());
							} else if (param instanceof String) {
								replaces.put("%%" + variable + "%%", param.toString());
							} else if (param instanceof Object) {
								replaces.put("%%" + variable + ".canonicalName%%", ((Object) param).getClass().getCanonicalName());
								replaces.put("%%" + variable + ".simpleName%%", ((Object) param).getClass().getSimpleName());
							} else if (param != null) {
								try {
									replaces.put("%%" + variable + "%%", param.toString());
								} catch (Exception e) {
									replaces.put("%%" + variable + "%%", "<" + variable + ":unserializable>");
								}
							}
						} catch (Exception e) {
							System.err.println(e.getLocalizedMessage());
						}
						variable = null;
					} else if (param instanceof Throwable) {
						causedBy((Throwable) param);
					} else if (param instanceof String) {
						variable = (String) param;
					} else {
						System.err.println("error handling params");
					}
				}
			}
			if (dslMetadataService != null) {
				// log messages should NEVER be translated - we talked about
				// this!!
				// fLogMessage =
				// fTranslator.getTranslations().get(fI18nKey+".log");
				// if (fLogMessage == null) {
				// fLogMessage =
				// fTranslator.getTranslations().get(fI18nKey+".show");
				// }
				// if (fLogMessage == null) {
				// fLogMessage = fLogFormat;
				// }
				// sure this ever worked??
				// fShowMessage =
				// fTranslator.getTranslations().get(fI18nKey+".show");
				// if (fShowMessage == null) {
				// fShowMessage =
				// fTranslator.getTranslations().get(fI18nKey+".log");
				// }
				// if (fShowMessage == null) {
				// fShowMessage = fShowFormat;
				// }
				fShowMessage = dslMetadataService.translate(locale.toLanguageTag(), fI18nKey);
			} else {
				fLogMessage = BasicTranslator.translate(fI18nKey + ".log", fI18nKey + ".show", fLogFormat);
				fShowMessage = BasicTranslator.translate(fI18nKey + ".show", fI18nKey + ".log", fShowFormat);
			}
			for (String key : replaces.keySet()) {
				fLogMessage = fLogMessage.replaceAll(key, replaces.get(key));
			}
			for (String key : replaces.keySet()) {
				fShowMessage = fShowMessage.replaceAll(key, replaces.get(key));
			}
		}
	}

	public String getLoggerName() {
		if (fLogger != null) {
			return fLogger.getName();
		} else {
			return fMessageGroup.getClass().getCanonicalName();
		}
	}

	@Override
	public String getLocalizedMessage() {
		return getLogMessage();
	}

	@Override
	public String getMessage() {
		return getLogMessage();
	}

	public String getLocalizedDetailMessage(Exception ex) {
		ExceptionMessageHelper exceptionHelper = getExceptionHelper(ex, new ExceptionMessageHelper());
		// return getLogMessage();
		StringBuffer strBuf = new StringBuffer();
		if (exceptionHelper.getErrorCode() > 1) {
			strBuf.append("Error code: ");
			strBuf.append(exceptionHelper.getErrorCode());
		}
		if (!exceptionHelper.getExceptionTree().isEmpty()) {
			strBuf.append("\n");
			strBuf.append("Exception tree: ");
			strBuf.append(exceptionHelper.getExceptionTree());
		}
		if (!exceptionHelper.getDetailMessage().isEmpty()) {
			strBuf.append("\n");
			strBuf.append("Detail message: ");
			strBuf.append(exceptionHelper.getDetailMessage());
		}
		if (!exceptionHelper.getCall().isEmpty()) {
			strBuf.append("\n");
			strBuf.append("Call: ");
			strBuf.append(exceptionHelper.getCall());
		}
		if (strBuf.toString().isEmpty()) {
			strBuf.append("Undefined Error!");
		}
		return strBuf.toString();
	}

	public String getLocalizedSimpleDetailMessage(Exception ex) {
		ExceptionMessageHelper exceptionHelper = getExceptionHelper(ex, new ExceptionMessageHelper());
		// return getLogMessage();
		StringBuffer strBuf = new StringBuffer();
		if (!exceptionHelper.getDetailMessage().isEmpty()) {
			strBuf.append(exceptionHelper.getDetailMessage());
		}
		if (!exceptionHelper.getCall().isEmpty()) {
			strBuf.append("\n");
			strBuf.append(exceptionHelper.getCall());
		}
		if (strBuf.toString().isEmpty()) {
			strBuf.append("Undefined Error!");
		}
		return strBuf.toString();
	}

	private ExceptionMessageHelper getExceptionHelper(Throwable thrble, ExceptionMessageHelper exceptionHelper) {
		Throwable cause = thrble.getCause();
		String exceptionTree = exceptionHelper.getExceptionTree();
		exceptionTree = exceptionTree.concat(thrble.getClass().getSimpleName());
		if ((cause != null) && !thrble.equals(cause)) {
			exceptionHelper.setExceptionTree(exceptionTree.concat("->"));
			exceptionHelper = getExceptionHelper(cause, exceptionHelper);
		} else {
			exceptionHelper.setExceptionTree(exceptionTree);
			exceptionHelper.setDetailMessage(((Exception) thrble).getMessage());
		}
		if (thrble instanceof DatabaseException) {
			Call call = ((DatabaseException) thrble).getCall();
			if (call instanceof DatabaseCall) {
				exceptionHelper.setCall(((DatabaseCall) call).getSQLString());
			}
		}
		if (thrble instanceof EclipseLinkException) {
			exceptionHelper.setErrorCode(((EclipseLinkException) thrble).getErrorCode());
		}
		return exceptionHelper;
	}

	public String getLogMessage() {
		prepareMessage();
		return fLogMessage;
	}

	public String getShowMessage() {
		prepareMessage();
		return fShowMessage;
	}

	public Message causedBy(Throwable causedBy) {
		try {
			initCause(causedBy);
		} catch (Exception e) {
			System.err.println(e.getLocalizedMessage());
		}
		return this;
	}

	public Message showInfo() {
		// System.out.println("info : "+getShowMessage());
		MessageBroker.instance().showInfo(this);
		return this;
	}

	public Message showWarn() {
		// System.out.println("warn : "+getShowMessage());
		MessageBroker.instance().showWarn(this);
		return this;
	}

	public Message showError() {
		// System.err.println("error: "+getShowMessage());
		MessageBroker.instance().showError(this);
		return this;
	}

	public Message logTrace() {
		// System.out.println("TRACE: "+getLogMessage());
		if ((fLogger != null) && fLogger.isTraceEnabled()) {
			fLogger.trace(getLogMessage());
		}
		MessageBroker.instance().logTrace(this);
		return this;
	}

	public Message logDebug() {
		// System.out.println("DEBUG: "+getLogMessage());
		if ((fLogger != null) && fLogger.isDebugEnabled()) {
			fLogger.debug(getLogMessage());
		}
		MessageBroker.instance().logDebug(this);
		return this;
	}

	public Message logInfo() {
		// System.out.println("INFO : "+getLogMessage());
		if ((fLogger != null) && fLogger.isInfoEnabled()) {
			fLogger.info(getLogMessage());
		}
		MessageBroker.instance().logInfo(this);
		return this;
	}

	public Message logWarn() {
		// System.out.println("WARN : "+getLogMessage());
		if ((fLogger != null) && fLogger.isWarnEnabled()) {
			fLogger.warn(getLogMessage());
		}
		MessageBroker.instance().logWarn(this);
		return this;
	}

	public Message logError() {
		// System.err.println("ERROR: "+getLogMessage());
		if ((fLogger != null) && fLogger.isErrorEnabled()) {
			fLogger.error(getLogMessage());
		}
		MessageBroker.instance().logError(this);
		return this;
	}

	public void throwit() throws Throwable {
		throw this;
	}

	private class ExceptionMessageHelper {
		private String exceptionTree = "";
		private String call = "";
		private String detailMessage = "";
		private int errorCode = 0;

		public String getExceptionTree() {
			return exceptionTree;
		}

		public void setExceptionTree(String exceptionTree) {
			this.exceptionTree = exceptionTree;
		}

		public String getCall() {
			return call;
		}

		public void setCall(String call) {
			this.call = call;
		}

		public int getErrorCode() {
			return errorCode;
		}

		public void setErrorCode(int errorCode) {
			this.errorCode = errorCode;
		}

		public String getDetailMessage() {
			return detailMessage;
		}

		public void setDetailMessage(String detailMessage) {
			this.detailMessage = detailMessage;
		}

	}
}
