
package de.ivu.elect.business.system.entity;

import java.util.regex.Pattern;

import org.apache.deltaspike.core.api.scope.ConversationGroup;
import org.apache.deltaspike.core.api.scope.GroupedConversationScoped;

import de.ivu.elect.business.search.control.AbstractElectSearchParameters;
import de.ivu.elect.jee.presentation.dynamicform.AbstractStringProperty;


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

@GroupedConversationScoped
@ConversationGroup(ThreadDumpFilterParameters.class)
public class ThreadDumpFilterParameters extends AbstractElectSearchParameters {

  private static final long serialVersionUID = 1L;

  private String threadName;

  private String stackTraceContent;

  private transient ThreadNameProperties threadNameProperty;

  private transient StackTraceContentProperties stackTraceContentProperty;

  public ThreadDumpFilterParameters() {
    super();
  }

  public Pattern getThreadNameRegexPattern() {
    return Pattern.compile(wildcardToRegex(getThreadName()));
  }

  public boolean isThreadNameSet() {
    return isNotBlank(getThreadName());
  }

  public String getThreadName() {
    return threadName;
  }

  public void setThreadName(String threadName) {
    this.threadName = threadName;
  }

  public ThreadNameProperties getThreadNameProperty() {
    if (threadNameProperty == null) {
      threadNameProperty = new ThreadNameProperties(this);
    }

    return threadNameProperty;
  }

  public Pattern getStackTraceRegexPattern() {
    return Pattern.compile(wildcardToRegex(getStackTraceContent()));
  }

  public boolean isStackTraceContentSet() {
    return isNotBlank(getStackTraceContent());
  }

  public String getStackTraceContent() {
    return stackTraceContent;
  }

  public void setStackTraceContent(String stackTraceContent) {
    this.stackTraceContent = stackTraceContent;
  }

  public StackTraceContentProperties getStackTraceContentProperty() {
    if (stackTraceContentProperty == null) {
      stackTraceContentProperty = new StackTraceContentProperties(this);
    }

    return stackTraceContentProperty;
  }

  @Override
  public void reset() {
    super.reset();
    setThreadName(null);
    setStackTraceContent(null);
  }

  private static String wildcardToRegex(String wildcardString) {
    if (isNotBlank(wildcardString)) {
      return wildcardString.replaceAll("[]\\[(){}.]", "\\\\$0").replaceAll("\\*", ".*").replaceAll("\\?", ".");
    }

    return ".*";
  }

  public static class ThreadNameProperties extends AbstractStringProperty {

    private final ThreadDumpFilterParameters filterParameters;

    public ThreadNameProperties(ThreadDumpFilterParameters filterParameters) {
      this.filterParameters = filterParameters;
    }

    @Override
    public String getValue() {
      return filterParameters.getThreadName();
    }

    @Override
    public void setValue(String value) {
      filterParameters.setThreadName(value);
    }

    @Override
    public int getDefaultMaxLength() {
      return 255;
    }

    @Override
    public String getDefaultLabel() {
      return "Name";
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }
  }

  public static class StackTraceContentProperties extends AbstractStringProperty {

    private final ThreadDumpFilterParameters filterParameters;

    public StackTraceContentProperties(ThreadDumpFilterParameters filterParameters) {
      this.filterParameters = filterParameters;
    }

    @Override
    public String getValue() {
      return filterParameters.getStackTraceContent();
    }

    @Override
    public void setValue(String value) {
      filterParameters.setStackTraceContent(value);
    }

    @Override
    public int getDefaultMaxLength() {
      return 255;
    }

    @Override
    public String getDefaultLabel() {
      return "Stacktrace";
    }

    @Override
    public boolean getDefaultRequired() {
      return false;
    }
  }
}
