/*
 * 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;

/**
 * A single result from a search request.
 *
 * @coverage dart.server.generated.types
 */
@SuppressWarnings("unused")
public class SearchResult {

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

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

  /**
   * The location of the code that matched the search criteria.
   */
  private final Location location;

  /**
   * The kind of element that was found or the kind of reference that was found.
   */
  private final String kind;

  /**
   * True if the result is a potential match but cannot be confirmed to be a match. For example, if
   * all references to a method m defined in some class were requested, and a reference to a method m
   * from an unknown class were found, it would be marked as being a potential match.
   */
  private final boolean isPotential;

  /**
   * The elements that contain the result, starting with the most immediately enclosing ancestor and
   * ending with the library.
   */
  private final List<Element> path;

  /**
   * Constructor for {@link SearchResult}.
   */
  public SearchResult(Location location, String kind, boolean isPotential, List<Element> path) {
    this.location = location;
    this.kind = kind;
    this.isPotential = isPotential;
    this.path = path;
  }

  @Override
  public boolean equals(Object obj) {
    if (obj instanceof SearchResult) {
      SearchResult other = (SearchResult) obj;
      return
        ObjectUtilities.equals(other.location, location) &&
        ObjectUtilities.equals(other.kind, kind) &&
        other.isPotential == isPotential &&
        ObjectUtilities.equals(other.path, path);
    }
    return false;
  }

  public static SearchResult fromJson(JsonObject jsonObject) {
    Location location = Location.fromJson(jsonObject.get("location").getAsJsonObject());
    String kind = jsonObject.get("kind").getAsString();
    boolean isPotential = jsonObject.get("isPotential").getAsBoolean();
    List<Element> path = Element.fromJsonArray(jsonObject.get("path").getAsJsonArray());
    return new SearchResult(location, kind, isPotential, path);
  }

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

  /**
   * True if the result is a potential match but cannot be confirmed to be a match. For example, if
   * all references to a method m defined in some class were requested, and a reference to a method m
   * from an unknown class were found, it would be marked as being a potential match.
   */
  public boolean isPotential() {
    return isPotential;
  }

  /**
   * The kind of element that was found or the kind of reference that was found.
   */
  public String getKind() {
    return kind;
  }

  /**
   * The location of the code that matched the search criteria.
   */
  public Location getLocation() {
    return location;
  }

  /**
   * The elements that contain the result, starting with the most immediately enclosing ancestor and
   * ending with the library.
   */
  public List<Element> getPath() {
    return path;
  }

  @Override
  public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(location);
    builder.append(kind);
    builder.append(isPotential);
    builder.append(path);
    return builder.toHashCode();
  }

  public JsonObject toJson() {
    JsonObject jsonObject = new JsonObject();
    jsonObject.add("location", location.toJson());
    jsonObject.addProperty("kind", kind);
    jsonObject.addProperty("isPotential", isPotential);
    JsonArray jsonArrayPath = new JsonArray();
    for (Element elt : path) {
      jsonArrayPath.add(elt.toJson());
    }
    jsonObject.add("path", jsonArrayPath);
    return jsonObject;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("[");
    builder.append("location=");
    builder.append(location + ", ");
    builder.append("kind=");
    builder.append(kind + ", ");
    builder.append("isPotential=");
    builder.append(isPotential + ", ");
    builder.append("path=");
    builder.append(StringUtils.join(path, ", "));
    builder.append("]");
    return builder.toString();
  }

}
