package com.fitbank.exception;

import com.fitbank.common.exception.FitbankException;
import com.fitbank.common.logger.FitbankLogger;
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;

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) {
    exception=pException;
    exception.printStackTrace();
    if(pLanguage != null){
      language=pLanguage.toLowerCase();
    }
  }

  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 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 getUserMessage(){
    String message=this.exception.getMessage();
    Locale locale = new Locale(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 ExceptionManager getExceptionManager() {
  	 try{
  	 Exceptions param=Exceptions.getInstance();
  	 String className=param.getValue(this.exception.getClass().getName());
  	 return (ExceptionManager)Class.forName(className).newInstance();
  	 }catch(Exception e){
  		 log.warn("Al obtener el Exception manager "+this.exception.getClass().getName());
  		 return null;
  	 }
   }

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

  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;
  }
}
