package kr.jm.utils.exception;

import kr.jm.utils.AutoStringBuilder;
import kr.jm.utils.helper.JMLog;
import kr.jm.utils.helper.JMResources;
import org.slf4j.Logger;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

public class JMExceptionManager {

    private static final String ERROR_HISTORY_SIZE = "error.history.size";

    static {
        JMResources.setSystemPropertyIfIsNull(ERROR_HISTORY_SIZE, 500);
    }

    private static final String LINE_SEPARATOR = System
            .getProperty("line.separator");
    private static final int maxQueueSize = new Integer(
            JMResources.getSystemProperty(ERROR_HISTORY_SIZE));

    private static List<ErrorMessageHistory> errorMessageHistoryList = new LinkedList<ErrorMessageHistory>();

    private static long errorCount = 0;

    public static void logException(Logger log, Exception e, String methodName,
                                    Object... params) {
        if (params.length > 0)
            JMLog.logException(log, e, methodName, params);
        else
            JMLog.logException(log, e, methodName);
        increaseErrorCount();
        recordErrorMessageHistory(e);
    }

    private static void recordErrorMessageHistory(Exception e) {
        if (errorMessageHistoryList.size() >= maxQueueSize)
            errorMessageHistoryList.remove(0);
        errorMessageHistoryList.add(new ErrorMessageHistory(System
                .currentTimeMillis(), getStackTraceString(e)));
    }

    private static String getStackTraceString(Throwable throwable) {
        AutoStringBuilder stackTraceStringBuilder = new AutoStringBuilder(
                LINE_SEPARATOR);
        stackTraceStringBuilder.append(throwable.toString());
        for (StackTraceElement stackTraceElement : throwable.getStackTrace())
            stackTraceStringBuilder.append(stackTraceElement.toString());
        return stackTraceStringBuilder.autoToString();
    }

    public static List<ErrorMessageHistory> getErrorMessageHistoryList() {
        return errorMessageHistoryList;
    }

    public static void clearAll() {
        removeErrorMessgeHistoryList();
        resetErrorCount();
    }

    public static void removeErrorMessgeHistoryList() {
        errorMessageHistoryList.clear();
    }

    public static long getErrorCount() {
        return errorCount;
    }

    public static void resetErrorCount() {
        errorCount = 0;
    }

    public static void increaseErrorCount() {
        errorCount++;
    }

    public static <T> T handleExceptionAndReturnNull(Logger log, Exception e,
                                                     String method, Object... params) {
        logException(log, e, method, params);
        return null;
    }

    public static boolean handleExceptionAndReturnFalse(Logger log,
                                                        Exception e, String method, Object... params) {
        logException(log, e, method, params);
        return false;
    }

    public static <T> T handleExceptionAndReturn(Logger log, Exception e,
                                                 String method, Supplier<T> returnSupplier, Object... params) {
        logException(log, e, method, params);
        return returnSupplier.get();
    }

    public static Object handleExceptionAndThrowRuntimeEx(Logger log, Exception e,
                                               String method, Object... params) {
        logException(log, e, method, params);
        throw new RuntimeException(e);
    }

    public static <T> Optional<T> handleExceptionAndReturnEmptyOptioal(
            Logger log, Exception e, String method, Object... params) {
        return Optional.empty();
    }

}

@@ -776,16 +776,28 @@
 st = new
+%0A           
  LinkedL
@@ -2703,32 +2703,93 @@
 ethod, Object...
+%0A                                                            
  params) %7B%0A     
@@ -2996,32 +2996,152 @@
 on e, String
- method,
+%0A                                                                method,%0A                                                       
  Object... p
@@ -3377,24 +3377,130 @@
 r%3CT%3E
- returnSupplier,
+%0A                                                         returnSupplier,%0A                                                
  Obj
@@ -3624,22 +3624,21 @@
  static 
-Object
+%3CT%3E T
  handleE
@@ -3666,32 +3666,89 @@
 meEx(Logger log,
+%0A                                                        
  Exception e,%0A  
@@ -3737,32 +3737,42 @@
    Exception e,%0A
+          
                 
@@ -3808,32 +3808,89 @@
   String method,
+%0A                                                        
  Object... param
@@ -4154,16 +4154,19 @@
 ptional.
+%3CT%3E
 empty();

add a method - JMExceptionManager.java