package com.mapbox.api.directions.v5.models;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.mapbox.api.directions.v5.DirectionsAdapterFactory;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.PointAsCoordinatesTypeAdapter;
import com.mapbox.auto.value.gson.SerializableJsonElement;
import com.mapbox.auto.value.gson.UnrecognizedJsonProperties;

import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * Provides a base class for Directions model classes.
 *
 * @since 3.4.0
 */
public abstract class DirectionsJsonObject implements Serializable {

  /**
   * This takes the currently defined values found inside this instance and converts it to a json
   * string.
   *
   * @return a JSON string which represents this DirectionsJsonObject
   * @since 3.4.0
   */
  public String toJson() {
    GsonBuilder gson = new GsonBuilder();
    gson.registerTypeAdapterFactory(DirectionsAdapterFactory.create());
    gson.registerTypeAdapter(Point.class, new PointAsCoordinatesTypeAdapter());
    return gson.create().toJson(this);
  }

  /**
   * Use this method to access a JSON property that wasn't recognized during JSON serialization.
   * This may be useful to access experimental properties.
   * @param propertyName name of a json property
   * @return value of a requested property or null if the requested property doesn't exist.
   */
  @Nullable
  public final JsonElement getUnrecognizedProperty(String propertyName) {
    JsonElement result = null;
    Map<String, SerializableJsonElement> unrecognizedProperties = unrecognized();
    if (unrecognizedProperties != null) {
      SerializableJsonElement property = unrecognizedProperties.get(propertyName);
      if (property != null) {
        result = property.getElement();
      }
    }
    return result;
  }

  /**
   * Use this method to get names of unrecognized JSON properties.
   * @return names of unrecognized JSON properties or an empty set
   */
  @NonNull
  public final Set<String> getUnrecognizedPropertiesNames() {
    Set<String> result;
    Map<String, SerializableJsonElement> unrecognizedProperties = unrecognized();
    if (unrecognizedProperties != null) {
      result = unrecognizedProperties.keySet();
    } else {
      result = Collections.emptySet();
    }
    return result;
  }

  @Nullable
  @UnrecognizedJsonProperties
  abstract Map<String, SerializableJsonElement> unrecognized();

  abstract static class Builder<T extends Builder> {
    @NonNull
    abstract T unrecognized(@Nullable Map<String, SerializableJsonElement> value);
  }
}

@@ -1296,22 +1296,35 @@
 lization
-.
 %0A   *
+ by the model.
  This ma
@@ -1358,16 +1358,20 @@
 imental 
+API 
 properti
@@ -1370,24 +1370,365 @@
 properties.%0A
+   * When an experimental API property becomes stable,%0A   * it will eventually have static field in a model introduced%0A   * and it won't be available via this dynamic method anymore.%0A   *%0A   * See%0A   * %3Ca href=%22https://docs.mapbox.com/api/navigation/directions/%22%3EDirections API documentation%3C/a%3E%0A   * for available experimental fields.%0A   *%0A
    * @param 
@@ -2341,37 +2341,541 @@
  of 
-unrecognized JSON properties.
+JSON properties that weren't recognized during JSON%0A   * serialization by the model. This may be useful to access experimental API properties%0A   * via %7B@link #getUnrecognizedProperty(String)%7D.%0A   * When an experimental API property becomes stable,%0A   * it will eventually have static field in a model introduced%0A   * and it won't be available via this dynamic method anymore.%0A   *%0A   * See%0A   * %3Ca href=%22https://docs.mapbox.com/api/navigation/directions/%22%3EDirections API documentation%3C/a%3E%0A   * for available experimental fields.%0A   *
 %0A   

improve unrecognized params docs