
package de.ivu.elect.jee.presentation.redirect;

import java.io.Serializable;

import javax.annotation.Nullable;
import javax.annotation.Priority;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.ivu.elect.jee.cdi.BeanManagerUtil;
import de.ivu.elect.jee.exception.ElectCommonExceptionHandler;


import static org.apache.commons.lang3.StringUtils.isBlank;

@Redirect
@Interceptor
@Priority(1) // ELECT-15185 enabled by default
public class RedirectInterceptor implements Serializable {

  private static final long serialVersionUID = 1L;

  private static final String REDIRECT_SUFFIX = "?faces-redirect=true";

  private static final Logger LOG = LoggerFactory.getLogger(RedirectInterceptor.class);

  public RedirectInterceptor() {
    super();
  }

  @Nullable
  @AroundInvoke
  public Object secure(InvocationContext ctx) throws Exception {
    try {
      Object proceed = ctx.proceed();

      if (proceed == null) {
        // HINT: Verhindert die Meldung "Kein übereinstimmendes navigation-case Element von View ID '...' für die Aktion '...' mit dem Ergebnis 'null?faces-redirect=true' gefunden."
        return null;
      }

      return concat(proceed.toString(), getRedirectSuffix());
    } catch (Exception ex) {
      ElectCommonExceptionHandler.handleException(ex);

      return null;
    }
  }

  public static String getRedirectSuffix() {
    return getRedirectSuffix(true);
  }

  public static String getRedirectSuffix(boolean includeRedirectParameter) {
    if (!includeRedirectParameter) {
      return REDIRECT_SUFFIX;
    }

    try {
      RedirectParameterAttachement redirectParameterAttachement = BeanManagerUtil.getBeanByClass(RedirectParameterAttachement.class);

      StringBuilder result = new StringBuilder();
      result.append(REDIRECT_SUFFIX);

      redirectParameterAttachement.getParameterMap().forEach((key, value) -> {
        result.append("&");
        result.append(key);
        result.append("=");
        result.append(value);
      });

      return result.toString();
    } catch (Exception e) {
      LOG.warn("Fehler beim REDIRECT_SUFFIX: " + e.getMessage(), e);
    }

    return REDIRECT_SUFFIX;
  }

  public static String concat(String viewId, String redirectSuffix) {
    if (isBlank(viewId)) {
      return redirectSuffix;
    }

    if (isBlank(redirectSuffix)) {
      return viewId;
    }

    if (viewId.contains("?") && redirectSuffix.startsWith("?")) {
      return viewId + "&" + redirectSuffix.substring(1);
    }

    return viewId + redirectSuffix;
  }
}
