/*
 * Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
 * for details. All rights reserved. Use of this source code is governed by a
 * BSD-style license that can be found in the LICENSE file.
 *
 * This file has been automatically generated. Please do not edit it manually.
 * To regenerate the file, use the script "pkg/analysis_server/tool/spec/generate_files".
 */
package org.dartlang.analysis.server.protocol;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import com.google.common.collect.Lists;
import com.google.dart.server.utilities.general.JsonUtilities;
import com.google.dart.server.utilities.general.ObjectUtilities;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.lang3.StringUtils;

/**
 * An node in the outline structure of a file.
 *
 * @coverage dart.server.generated.types
 */
@SuppressWarnings("unused")
public class Outline {

  public static final Outline[] EMPTY_ARRAY = new Outline[0];

  public static final List<Outline> EMPTY_LIST = Lists.newArrayList();

  /**
   * A description of the element represented by this node.
   */
  private Element element;

  /**
   * The offset of the first character of the element. This is different than the offset in the
   * Element, which is the offset of the name of the element. It can be used, for example, to map
   * locations in the file back to an outline.
   */
  private int offset;

  /**
   * The length of the element.
   */
  private int length;

  /**
   * The offset of the first character of the element code, which is neither documentation, nor
   * annotation.
   */
  private int codeOffset;

  /**
   * The length of the element code.
   */
  private int codeLength;

  private final Outline parent;

  private List<Outline> children;

  /**
   * Constructor for {@link Outline}.
   */
  public Outline(Outline parent, Element element, int offset, int length, int codeOffset, int codeLength) {
    this.parent = parent;
    this.element = element;
    this.offset = offset;
    this.length = length;
    this.codeOffset = codeOffset;
    this.codeLength = codeLength;
  }

  public boolean containsInclusive(int x) {
    return offset <= x && x <= offset + length;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof Outline) {
      Outline other = (Outline) obj;
      return
        ObjectUtilities.equals(other.element, element) &&
        other.offset == offset &&
        other.length == length &&
        other.codeOffset == codeOffset &&
        other.codeLength == codeLength &&
        ObjectUtilities.equals(other.children, children);
    }
    return false;
  }

  public static Outline fromJson(Outline parent, JsonObject outlineObject) {
    JsonObject elementObject = outlineObject.get("element").getAsJsonObject();
    Element element = Element.fromJson(elementObject);
    int offset = outlineObject.get("offset").getAsInt();
    int length = outlineObject.get("length").getAsInt();

    // create outline object
    Outline outline = new Outline(parent, element, offset, length);

    // compute children recursively
    List<Outline> childrenList = Lists.newArrayList();
    JsonElement childrenJsonArray = outlineObject.get("children");
    if (childrenJsonArray instanceof JsonArray) {
      Iterator<JsonElement> childrenElementIterator = ((JsonArray) childrenJsonArray).iterator();
      while (childrenElementIterator.hasNext()) {
        JsonObject childObject = childrenElementIterator.next().getAsJsonObject();
        childrenList.add(fromJson(outline, childObject));
      }
    }
    outline.setChildren(childrenList);
    return outline;
  }

  public Outline getParent() {
    return parent;
  }

  /**
   * The children of the node. The field will be omitted if the node has no children. Children are
   * sorted by offset.
   */
  public List<Outline> getChildren() {
    return children;
  }

  /**
   * The length of the element code.
   */
  public int getCodeLength() {
    return codeLength;
  }

  /**
   * The offset of the first character of the element code, which is neither documentation, nor
   * annotation.
   */
  public int getCodeOffset() {
    return codeOffset;
  }

  /**
   * A description of the element represented by this node.
   */
  public Element getElement() {
    return element;
  }

  /**
   * The length of the element.
   */
  public int getLength() {
    return length;
  }

  /**
   * The offset of the first character of the element. This is different than the offset in the
   * Element, which is the offset of the name of the element. It can be used, for example, to map
   * locations in the file back to an outline.
   */
  public int getOffset() {
    return offset;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(element);
    builder.append(offset);
    builder.append(length);
    builder.append(codeOffset);
    builder.append(codeLength);
    builder.append(children);
    return builder.toHashCode();
  }

  /**
   * The children of the node. The field will be omitted if the node has no children. Children are
   * sorted by offset.
   */
  public void setChildren(List<Outline> children) {
    this.children = children;
  }

  /**
   * The length of the element code.
   */
  public void setCodeLength(int codeLength) {
    this.codeLength = codeLength;
  }

  /**
   * The offset of the first character of the element code, which is neither documentation, nor
   * annotation.
   */
  public void setCodeOffset(int codeOffset) {
    this.codeOffset = codeOffset;
  }

  /**
   * A description of the element represented by this node.
   */
  public void setElement(Element element) {
    this.element = element;
  }

  /**
   * The length of the element.
   */
  public void setLength(int length) {
    this.length = length;
  }

  /**
   * The offset of the first character of the element. This is different than the offset in the
   * Element, which is the offset of the name of the element. It can be used, for example, to map
   * locations in the file back to an outline.
   */
  public void setOffset(int offset) {
    this.offset = offset;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("[");
    builder.append("element=");
    builder.append(element + ", ");
    builder.append("offset=");
    builder.append(offset + ", ");
    builder.append("length=");
    builder.append(length + ", ");
    builder.append("codeOffset=");
    builder.append(codeOffset + ", ");
    builder.append("codeLength=");
    builder.append(codeLength + ", ");
    builder.append("children=");
    builder.append(StringUtils.join(children, ", "));
    builder.append("]");
    return builder.toString();
  }

}
