/*
 * Copyright (c) 2014, the Dart project authors.
 *
 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 *
 * 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 com.google.dart.server.generated.types;

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;

/**
 * A collection of positions that should be linked (edited simultaneously) for the purposes of
 * updating code after a source change. For example, if a set of edits introduced a new variable
 * name, the group would contain all of the positions of the variable name so that if the client
 * wanted to let the user edit the variable name after the operation, all occurrences of the name
 * could be edited simultaneously.
 *
 * @coverage dart.server.generated.types
 */
@SuppressWarnings("unused")
public class LinkedEditGroup {

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

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

  /**
   * The positions of the regions that should be edited simultaneously.
   */
  private final List<Position> positions;

  /**
   * The length of the regions that should be edited simultaneously.
   */
  private final int length;

  /**
   * Pre-computed suggestions for what every region might want to be changed to.
   */
  private final List<LinkedEditSuggestion> suggestions;

  /**
   * Constructor for {@link LinkedEditGroup}.
   */
  public LinkedEditGroup(List<Position> positions, int length, List<LinkedEditSuggestion> suggestions) {
    this.positions = positions;
    this.length = length;
    this.suggestions = suggestions;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof LinkedEditGroup) {
      LinkedEditGroup other = (LinkedEditGroup) obj;
      return
        ObjectUtilities.equals(other.positions, positions) &&
        other.length == length &&
        ObjectUtilities.equals(other.suggestions, suggestions);
    }
    return false;
  }

  public static LinkedEditGroup fromJson(JsonObject jsonObject) {
    List<Position> positions = Position.fromJsonArray(jsonObject.get("positions").getAsJsonArray());
    int length = jsonObject.get("length").getAsInt();
    List<LinkedEditSuggestion> suggestions = LinkedEditSuggestion.fromJsonArray(jsonObject.get("suggestions").getAsJsonArray());
    return new LinkedEditGroup(positions, length, suggestions);
  }

  public static List<LinkedEditGroup> fromJsonArray(JsonArray jsonArray) {
    if (jsonArray == null) {
      return EMPTY_LIST;
    }
    ArrayList<LinkedEditGroup> list = new ArrayList<LinkedEditGroup>(jsonArray.size());
    Iterator<JsonElement> iterator = jsonArray.iterator();
    while (iterator.hasNext()) {
      list.add(fromJson(iterator.next().getAsJsonObject()));
    }
    return list;
  }

  /**
   * The length of the regions that should be edited simultaneously.
   */
  public int getLength() {
    return length;
  }

  /**
   * The positions of the regions that should be edited simultaneously.
   */
  public List<Position> getPositions() {
    return positions;
  }

  /**
   * Pre-computed suggestions for what every region might want to be changed to.
   */
  public List<LinkedEditSuggestion> getSuggestions() {
    return suggestions;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(positions);
    builder.append(length);
    builder.append(suggestions);
    return builder.toHashCode();
  }

  public JsonObject toJson() {
    JsonObject jsonObject = new JsonObject();
    JsonArray jsonArrayPositions = new JsonArray();
    for (Position elt : positions) {
      jsonArrayPositions.add(elt.toJson());
    }
    jsonObject.add("positions", jsonArrayPositions);
    jsonObject.addProperty("length", length);
    JsonArray jsonArraySuggestions = new JsonArray();
    for (LinkedEditSuggestion elt : suggestions) {
      jsonArraySuggestions.add(elt.toJson());
    }
    jsonObject.add("suggestions", jsonArraySuggestions);
    return jsonObject;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("[");
    builder.append("positions=");
    builder.append(StringUtils.join(positions, ", ") + ", ");
    builder.append("length=");
    builder.append(length + ", ");
    builder.append("suggestions=");
    builder.append(StringUtils.join(suggestions, ", "));
    builder.append("]");
    return builder.toString();
  }

}
