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

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;

import javax.enterprise.context.RequestScoped;


import static java.util.Arrays.asList;

@RequestScoped
public class ConsoleLogInspector implements Serializable {

  public static final String JAVA_LANG = "java.lang.";

  private static final Set<String> WEGLASSEN = new HashSet<>(asList("equals", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait"));

  public String inspect(Object o) {

    if (o == null) {
      return null;
    }

    Class tClass = o.getClass();

    StringBuilder sb = new StringBuilder();
    sb.append("Methods (").append(typeToString(tClass)).append("):\n");

    Arrays.stream(tClass.getMethods())
        .filter(this::isMethodeAuffuehren)
        .sorted(Comparator.comparing(Method::getName).thenComparing(Method::getParameterCount)).forEach(m -> {

          sb.append(typeToString(m.getReturnType()));
          sb.append(" ");
          sb.append(m.getName());
          sb.append("(");
          boolean firstParameter = true;
          for (Parameter parameter : m.getParameters()) {
            if (firstParameter) {
              firstParameter = false;
            } else {
              sb.append(", ");
            }

            sb.append(typeToString(parameter.getType()));
            sb.append(" ");
            sb.append(parameter.getName());

          }

          sb.append(")\n");

        }

    );

    return sb.toString();
  }

  private String typeToString(Class<?> type) {
    if (type == null) {
      return null;
    }
    String name = type.getName();

    if (name.startsWith(JAVA_LANG)) {
      return name.substring(JAVA_LANG.length());
    }
    return name;

  }

  private boolean isMethodeAuffuehren(Method method) {
    return !WEGLASSEN.contains(method.getName());
  }
}
