package com.fitbank.exception;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;

import com.fitbank.common.exception.FitbankException;
import com.fitbank.common.logger.FitbankLogger;

public class ExceptionHandler {
	/**
	 * Referencia a la excepci�n presentanda
	 */
	private Throwable exception;

	private String language = "es";

	/**
	 * Referencia al Log
	 */
	private Logger log = FitbankLogger.getLogger();

	/**
	 * Crea una Instancia de ExceptionHandler
	 * 
	 * @param pException
	 *          Excepci�n por Manejar
	 */
	public ExceptionHandler(Throwable pException, String pLanguage) {
		this.exception = pException;
		this.exception.printStackTrace();
		if (pLanguage != null) {
			this.language = pLanguage.toLowerCase();
		}
	}

	public String getCode() {
		String code = this.exception.getClass().getName();
		if (this.exception instanceof FitbankException) {
			code = ((FitbankException) this.exception).getCode();
		}
		return code;
	}

	private ExceptionManager getExceptionManager() {
		try {
			Exceptions param = Exceptions.getInstance();
			String className = param.getValue(this.exception.getClass().getName());
			return (ExceptionManager) Class.forName(className).newInstance();
		} catch (Exception e) {
			this.log.warn("Al obtener el Exception manager " + this.exception.getClass().getName());
			return null;
		}
	}

	public String getStackTrace() {
		try {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			this.exception.printStackTrace(pw);
			String data = sw.toString();
			pw.close();
			return data;
		} catch (Exception e) {
			return null;
		}

	}

	public String getTechnicalMessage() {
		String message = this.exception.getMessage();
		StackTraceElement[] stack = this.exception.getStackTrace();
		for (StackTraceElement element : stack) {
			if (element.getClassName().indexOf("com.fitbank") > -1) {
				message += " " + element.getClassName() + " : " + element.getLineNumber();
				break;
			}
		}
		return message;
	}

	public String getUserMessage() {
		String message = this.exception.getMessage();
		Locale locale = new Locale(this.language, Locale.getDefault().getCountry(), this.getVariant());
		if (this.exception instanceof FitbankException) {
			message = ((FitbankException) this.exception).getMessage(locale);
		} else {
			ExceptionManager man = this.getExceptionManager();
			if (man == null) {
				try {
					ResourceBundle bdl = ResourceBundle.getBundle("userMessages", locale);
					message = bdl.getString(this.exception.getClass().getName());
				} catch (MissingResourceException e) {
					message = /* this.exception.getClass().getName()+" "+ */this.exception.getMessage();
				}
			} else {
				man.setLocale(locale);
				message = man.getUserMessage(this.exception);
			}
		}
		return message;
	}

	private String getVariant() {
		String code = "";
		for (int i = 0; i < this.getCode().length(); i++) {
			if (Character.isDigit(this.getCode().charAt(i))) {
				break;
			} else {
				code += this.getCode().charAt(i);
			}
		}
		return code;
	}
}
