/*
 * #%L
 * wcm.io
 * %%
 * Copyright (C) 2017 wcm.io
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package io.wcm.qa.galenium.appender.logback;

import org.slf4j.Marker;

import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
import io.wcm.qa.galenium.reporting.GalenReportUtil;

/**
 * Logback appender for writing to {@link ExtentReports}.
 */
public class ExtentAppender extends AppenderBase<ILoggingEvent> {

  @Override
  protected void append(ILoggingEvent event) {
    ExtentTest extentTest = GalenReportUtil.getExtentTest(event.getLoggerName());
    extentTest.log(extractLogStatus(event), event.getFormattedMessage());
  }

  private LogStatus extractLogStatus(ILoggingEvent event) {
    if (isExtentReportSpecial(event)) {
      if (isPass(event)) {
        return LogStatus.PASS;
      }
      if (isSkip(event)) {
        return LogStatus.SKIP;
      }
      if (isFail(event)) {
        return LogStatus.FAIL;
      }
      if (isFatal(event)) {
        return LogStatus.FATAL;
      }
    }
    if (isError(event)) {
      return LogStatus.ERROR;
    }
    if (isWarn(event)) {
      return LogStatus.WARNING;
    }
    if (isInfo(event)) {
      return LogStatus.INFO;
    }
    return LogStatus.UNKNOWN;
  }

  private boolean hasMarker(ILoggingEvent event, Marker marker) {
    if (event.getMarker() != null) {
      return event.getMarker().contains(marker);
    }
    return false;
  }

  private boolean isError(ILoggingEvent event) {
    return isLevel(event, Level.ERROR);
  }

  private boolean isExtentReportSpecial(ILoggingEvent event) {
    return hasMarker(event, GalenReportUtil.MARKER_EXTENT_REPORT);
  }

  private boolean isFail(ILoggingEvent event) {
    return hasMarker(event, GalenReportUtil.MARKER_FAIL);
  }

  private boolean isFatal(ILoggingEvent event) {
    return hasMarker(event, GalenReportUtil.MARKER_FAIL);
  }

  private boolean isInfo(ILoggingEvent event) {
    return isLevel(event, Level.INFO);
  }

  private boolean isLevel(ILoggingEvent event, Level level) {
    if (event.getLevel() != null) {
      return event.getLevel().isGreaterOrEqual(level);
    }
    return false;
  }

  private boolean isPass(ILoggingEvent event) {
    return hasMarker(event, GalenReportUtil.MARKER_PASS);
  }

  private boolean isSkip(ILoggingEvent event) {
    return hasMarker(event, GalenReportUtil.MARKER_SKIP);
  }

  private boolean isWarn(ILoggingEvent event) {
    return isLevel(event, Level.WARN);
  }

}

@@ -962,24 +962,171 @@
 ck.c
-ore.AppenderBase
+lassic.spi.IThrowableProxy;%0Aimport ch.qos.logback.classic.spi.ThrowableProxyUtil;%0Aimport ch.qos.logback.core.AppenderBase;%0Aimport ch.qos.logback.core.CoreConstants
 ;%0Aim
@@ -1160,24 +1160,27 @@
 orting.Galen
+ium
 ReportUtil;%0A
@@ -1401,24 +1401,27 @@
 Test = Galen
+ium
 ReportUtil.g
@@ -1457,16 +1457,515 @@
 ame());%0A
+    String formattedMessage = event.getFormattedMessage();%0A    IThrowableProxy throwableProxy = event.getThrowableProxy();%0A    if (throwableProxy != null) %7B%0A      StringBuilder sb = new StringBuilder();%0A      ThrowableProxyUtil.subjoinFirstLineRootCauseFirst(sb, throwableProxy);%0A      sb.append(CoreConstants.LINE_SEPARATOR);%0A      ThrowableProxyUtil.subjoinSTEPArray(sb, 2, throwableProxy);%0A      String stacktrace = sb.toString();%0A      formattedMessage += %22%3Cpre%3E%22 + stacktrace + %22%3C/pre%3E%22;%0A    %7D%0A
     exte
@@ -2000,26 +2000,17 @@
 event), 
-event.getF
+f
 ormatted
@@ -2016,18 +2016,16 @@
 dMessage
-()
 );%0A  %7D%0A%0A
@@ -2979,32 +2979,35 @@
 ker(event, Galen
+ium
 ReportUtil.MARKE
@@ -3102,32 +3102,35 @@
 ker(event, Galen
+ium
 ReportUtil.MARKE
@@ -3217,32 +3217,35 @@
 ker(event, Galen
+ium
 ReportUtil.MARKE
@@ -3605,32 +3605,35 @@
 ker(event, Galen
+ium
 ReportUtil.MARKE
@@ -3727,16 +3727,19 @@
 t, Galen
+ium
 ReportUt

add stacktrace to appender