package de.ivu.elect.presentation;

import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * ELECT-7773
 */
public class IvuCdataFilter implements Filter {
  private static final Pattern PREFIX_PATTERN = Pattern.compile("/* <![CDATA[ */", Pattern.LITERAL);

  private static final Pattern POSTFIX_PATTERN = Pattern.compile("/* ]]> */", Pattern.LITERAL);

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    // nichts zu tun
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
                       FilterChain filterChain) throws IOException, ServletException {
    if (!isAjax((HttpServletRequest) request) || ((HttpServletRequest) request).getServletPath().contains("javax.faces.resource")) {
      filterChain.doFilter(request, response);
    } else {

      IvuCdataHtmlResponseWrapper capturingResponseWrapper = new IvuCdataHtmlResponseWrapper((HttpServletResponse) response);

      filterChain.doFilter(request, capturingResponseWrapper);

      String content = capturingResponseWrapper.getCaptureAsString();

      String replacedContent;
      if (((HttpServletResponse) response).containsHeader(IvuCdata.HEADER_MARKER)) {
        ((HttpServletResponse) response).setHeader(IvuCdata.HEADER_MARKER, null);
        replacedContent = replaceCdata(content);
      } else {
        replacedContent = content;
      }

      response.getWriter().write(replacedContent);
    }
  }

  protected static String replaceCdata(String content) {
    return POSTFIX_PATTERN.matcher(PREFIX_PATTERN.matcher(content).replaceAll(Matcher.quoteReplacement(""))).replaceAll(Matcher.quoteReplacement(""));
  }

  private boolean isAjax(HttpServletRequest request) {
    return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
  }

  @Override
  public void destroy() {
    // nichts zu tun
  }
}
