package org.batfish.datamodel.trace;

import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.batfish.datamodel.TraceElement;

/** A node in a trace */
@ParametersAreNonnullByDefault
public final class TraceTree {
  private static final String PROP_TRACE_ELEMENT = "traceElement";
  private static final String PROP_CHILDREN = "children";

  private final @Nullable TraceElement _traceElement;
  private final @Nonnull List<TraceTree> _children;

  TraceTree(TraceElement traceElement, List<TraceTree> children) {
    _traceElement = traceElement;
    _children = ImmutableList.copyOf(children);
  }

  @JsonCreator
  private static TraceTree jsonCreator(
      @Nullable @JsonProperty(PROP_TRACE_ELEMENT) TraceElement traceElement,
      @Nullable @JsonProperty(PROP_CHILDREN) List<TraceTree> children) {
    checkNotNull(traceElement, "%s cannot be null", PROP_TRACE_ELEMENT);
    return new TraceTree(traceElement, firstNonNull(children, ImmutableList.of()));
  }

  @JsonProperty(PROP_CHILDREN)
  @Nonnull
  public List<TraceTree> getChildren() {
    return _children;
  }

  @JsonProperty(PROP_TRACE_ELEMENT)
  @Nullable
  public TraceElement getTraceElement() {
    return _traceElement;
  }

  @Override
  public boolean equals(@Nullable Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof TraceTree)) {
      return false;
    }
    TraceTree other = (TraceTree) o;
    return Objects.equals(_traceElement, other._traceElement) && _children.equals(other._children);
  }

  @Override
  public int hashCode() {
    return Objects.hash(_traceElement, _children);
  }
}

@@ -267,16 +267,59 @@
 operty;%0A
+import com.google.common.base.MoreObjects;%0A
 import c
@@ -2046,11 +2046,228 @@
 en);%0A  %7D
+%0A%0A  @Override%0A  public String toString() %7B%0A    return MoreObjects.toStringHelper(this)%0A        .omitNullValues()%0A        .add(%22traceElement%22, _traceElement)%0A        .add(%22children%22, _children)%0A        .toString();%0A  %7D
 %0A%7D%0A

implement toString (#6354)