/*
 * Daytona Toolbox API
 * Daytona Toolbox API
 *
 * The version of the OpenAPI document: v0.0.0-dev
 * 
 *
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */


package io.daytona.toolbox.client.model;

import java.util.Objects;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.daytona.toolbox.client.JSON;

/**
 * ChartElement
 */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.21.0")
public class ChartElement {
  public static final String SERIALIZED_NAME_ANGLE = "angle";
  @SerializedName(SERIALIZED_NAME_ANGLE)
  @javax.annotation.Nullable
  private BigDecimal angle;

  public static final String SERIALIZED_NAME_FIRST_QUARTILE = "first_quartile";
  @SerializedName(SERIALIZED_NAME_FIRST_QUARTILE)
  @javax.annotation.Nullable
  private BigDecimal firstQuartile;

  public static final String SERIALIZED_NAME_GROUP = "group";
  @SerializedName(SERIALIZED_NAME_GROUP)
  @javax.annotation.Nullable
  private String group;

  public static final String SERIALIZED_NAME_LABEL = "label";
  @SerializedName(SERIALIZED_NAME_LABEL)
  @javax.annotation.Nullable
  private String label;

  public static final String SERIALIZED_NAME_MAX = "max";
  @SerializedName(SERIALIZED_NAME_MAX)
  @javax.annotation.Nullable
  private BigDecimal max;

  public static final String SERIALIZED_NAME_MEDIAN = "median";
  @SerializedName(SERIALIZED_NAME_MEDIAN)
  @javax.annotation.Nullable
  private BigDecimal median;

  public static final String SERIALIZED_NAME_MIN = "min";
  @SerializedName(SERIALIZED_NAME_MIN)
  @javax.annotation.Nullable
  private BigDecimal min;

  public static final String SERIALIZED_NAME_OUTLIERS = "outliers";
  @SerializedName(SERIALIZED_NAME_OUTLIERS)
  @javax.annotation.Nullable
  private List<BigDecimal> outliers = new ArrayList<>();

  public static final String SERIALIZED_NAME_PNG = "png";
  @SerializedName(SERIALIZED_NAME_PNG)
  @javax.annotation.Nullable
  private String png;

  public static final String SERIALIZED_NAME_POINTS = "points";
  @SerializedName(SERIALIZED_NAME_POINTS)
  @javax.annotation.Nullable
  private List<List<BigDecimal>> points = new ArrayList<>();

  public static final String SERIALIZED_NAME_RADIUS = "radius";
  @SerializedName(SERIALIZED_NAME_RADIUS)
  @javax.annotation.Nullable
  private BigDecimal radius;

  public static final String SERIALIZED_NAME_THIRD_QUARTILE = "third_quartile";
  @SerializedName(SERIALIZED_NAME_THIRD_QUARTILE)
  @javax.annotation.Nullable
  private BigDecimal thirdQuartile;

  public static final String SERIALIZED_NAME_TITLE = "title";
  @SerializedName(SERIALIZED_NAME_TITLE)
  @javax.annotation.Nullable
  private String title;

  public static final String SERIALIZED_NAME_TYPE = "type";
  @SerializedName(SERIALIZED_NAME_TYPE)
  @javax.annotation.Nullable
  private String type;

  public static final String SERIALIZED_NAME_VALUE = "value";
  @SerializedName(SERIALIZED_NAME_VALUE)
  @javax.annotation.Nullable
  private String value;

  public static final String SERIALIZED_NAME_X_LABEL = "x_label";
  @SerializedName(SERIALIZED_NAME_X_LABEL)
  @javax.annotation.Nullable
  private String xLabel;

  public static final String SERIALIZED_NAME_Y_LABEL = "y_label";
  @SerializedName(SERIALIZED_NAME_Y_LABEL)
  @javax.annotation.Nullable
  private String yLabel;

  public ChartElement() {
  }

  public ChartElement angle(@javax.annotation.Nullable BigDecimal angle) {
    this.angle = angle;
    return this;
  }

  /**
   * Get angle
   * @return angle
   */
  @javax.annotation.Nullable
  public BigDecimal getAngle() {
    return angle;
  }

  public void setAngle(@javax.annotation.Nullable BigDecimal angle) {
    this.angle = angle;
  }


  public ChartElement firstQuartile(@javax.annotation.Nullable BigDecimal firstQuartile) {
    this.firstQuartile = firstQuartile;
    return this;
  }

  /**
   * Get firstQuartile
   * @return firstQuartile
   */
  @javax.annotation.Nullable
  public BigDecimal getFirstQuartile() {
    return firstQuartile;
  }

  public void setFirstQuartile(@javax.annotation.Nullable BigDecimal firstQuartile) {
    this.firstQuartile = firstQuartile;
  }


  public ChartElement group(@javax.annotation.Nullable String group) {
    this.group = group;
    return this;
  }

  /**
   * Get group
   * @return group
   */
  @javax.annotation.Nullable
  public String getGroup() {
    return group;
  }

  public void setGroup(@javax.annotation.Nullable String group) {
    this.group = group;
  }


  public ChartElement label(@javax.annotation.Nullable String label) {
    this.label = label;
    return this;
  }

  /**
   * Get label
   * @return label
   */
  @javax.annotation.Nullable
  public String getLabel() {
    return label;
  }

  public void setLabel(@javax.annotation.Nullable String label) {
    this.label = label;
  }


  public ChartElement max(@javax.annotation.Nullable BigDecimal max) {
    this.max = max;
    return this;
  }

  /**
   * Get max
   * @return max
   */
  @javax.annotation.Nullable
  public BigDecimal getMax() {
    return max;
  }

  public void setMax(@javax.annotation.Nullable BigDecimal max) {
    this.max = max;
  }


  public ChartElement median(@javax.annotation.Nullable BigDecimal median) {
    this.median = median;
    return this;
  }

  /**
   * Get median
   * @return median
   */
  @javax.annotation.Nullable
  public BigDecimal getMedian() {
    return median;
  }

  public void setMedian(@javax.annotation.Nullable BigDecimal median) {
    this.median = median;
  }


  public ChartElement min(@javax.annotation.Nullable BigDecimal min) {
    this.min = min;
    return this;
  }

  /**
   * Get min
   * @return min
   */
  @javax.annotation.Nullable
  public BigDecimal getMin() {
    return min;
  }

  public void setMin(@javax.annotation.Nullable BigDecimal min) {
    this.min = min;
  }


  public ChartElement outliers(@javax.annotation.Nullable List<BigDecimal> outliers) {
    this.outliers = outliers;
    return this;
  }

  public ChartElement addOutliersItem(BigDecimal outliersItem) {
    if (this.outliers == null) {
      this.outliers = new ArrayList<>();
    }
    this.outliers.add(outliersItem);
    return this;
  }

  /**
   * Get outliers
   * @return outliers
   */
  @javax.annotation.Nullable
  public List<BigDecimal> getOutliers() {
    return outliers;
  }

  public void setOutliers(@javax.annotation.Nullable List<BigDecimal> outliers) {
    this.outliers = outliers;
  }


  public ChartElement png(@javax.annotation.Nullable String png) {
    this.png = png;
    return this;
  }

  /**
   * Get png
   * @return png
   */
  @javax.annotation.Nullable
  public String getPng() {
    return png;
  }

  public void setPng(@javax.annotation.Nullable String png) {
    this.png = png;
  }


  public ChartElement points(@javax.annotation.Nullable List<List<BigDecimal>> points) {
    this.points = points;
    return this;
  }

  public ChartElement addPointsItem(List<BigDecimal> pointsItem) {
    if (this.points == null) {
      this.points = new ArrayList<>();
    }
    this.points.add(pointsItem);
    return this;
  }

  /**
   * Get points
   * @return points
   */
  @javax.annotation.Nullable
  public List<List<BigDecimal>> getPoints() {
    return points;
  }

  public void setPoints(@javax.annotation.Nullable List<List<BigDecimal>> points) {
    this.points = points;
  }


  public ChartElement radius(@javax.annotation.Nullable BigDecimal radius) {
    this.radius = radius;
    return this;
  }

  /**
   * Get radius
   * @return radius
   */
  @javax.annotation.Nullable
  public BigDecimal getRadius() {
    return radius;
  }

  public void setRadius(@javax.annotation.Nullable BigDecimal radius) {
    this.radius = radius;
  }


  public ChartElement thirdQuartile(@javax.annotation.Nullable BigDecimal thirdQuartile) {
    this.thirdQuartile = thirdQuartile;
    return this;
  }

  /**
   * Get thirdQuartile
   * @return thirdQuartile
   */
  @javax.annotation.Nullable
  public BigDecimal getThirdQuartile() {
    return thirdQuartile;
  }

  public void setThirdQuartile(@javax.annotation.Nullable BigDecimal thirdQuartile) {
    this.thirdQuartile = thirdQuartile;
  }


  public ChartElement title(@javax.annotation.Nullable String title) {
    this.title = title;
    return this;
  }

  /**
   * Get title
   * @return title
   */
  @javax.annotation.Nullable
  public String getTitle() {
    return title;
  }

  public void setTitle(@javax.annotation.Nullable String title) {
    this.title = title;
  }


  public ChartElement type(@javax.annotation.Nullable String type) {
    this.type = type;
    return this;
  }

  /**
   * Get type
   * @return type
   */
  @javax.annotation.Nullable
  public String getType() {
    return type;
  }

  public void setType(@javax.annotation.Nullable String type) {
    this.type = type;
  }


  public ChartElement value(@javax.annotation.Nullable String value) {
    this.value = value;
    return this;
  }

  /**
   * Get value
   * @return value
   */
  @javax.annotation.Nullable
  public String getValue() {
    return value;
  }

  public void setValue(@javax.annotation.Nullable String value) {
    this.value = value;
  }


  public ChartElement xLabel(@javax.annotation.Nullable String xLabel) {
    this.xLabel = xLabel;
    return this;
  }

  /**
   * Get xLabel
   * @return xLabel
   */
  @javax.annotation.Nullable
  public String getxLabel() {
    return xLabel;
  }

  public void setxLabel(@javax.annotation.Nullable String xLabel) {
    this.xLabel = xLabel;
  }


  public ChartElement yLabel(@javax.annotation.Nullable String yLabel) {
    this.yLabel = yLabel;
    return this;
  }

  /**
   * Get yLabel
   * @return yLabel
   */
  @javax.annotation.Nullable
  public String getyLabel() {
    return yLabel;
  }

  public void setyLabel(@javax.annotation.Nullable String yLabel) {
    this.yLabel = yLabel;
  }

  /**
   * A container for additional, undeclared properties.
   * This is a holder for any undeclared properties as specified with
   * the 'additionalProperties' keyword in the OAS document.
   */
  private Map<String, Object> additionalProperties;

  /**
   * Set the additional (undeclared) property with the specified name and value.
   * If the property does not already exist, create it otherwise replace it.
   *
   * @param key name of the property
   * @param value value of the property
   * @return the ChartElement instance itself
   */
  public ChartElement putAdditionalProperty(String key, Object value) {
    if (this.additionalProperties == null) {
        this.additionalProperties = new HashMap<String, Object>();
    }
    this.additionalProperties.put(key, value);
    return this;
  }

  /**
   * Return the additional (undeclared) property.
   *
   * @return a map of objects
   */
  public Map<String, Object> getAdditionalProperties() {
    return additionalProperties;
  }

  /**
   * Return the additional (undeclared) property with the specified name.
   *
   * @param key name of the property
   * @return an object
   */
  public Object getAdditionalProperty(String key) {
    if (this.additionalProperties == null) {
        return null;
    }
    return this.additionalProperties.get(key);
  }


  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ChartElement chartElement = (ChartElement) o;
    return Objects.equals(this.angle, chartElement.angle) &&
        Objects.equals(this.firstQuartile, chartElement.firstQuartile) &&
        Objects.equals(this.group, chartElement.group) &&
        Objects.equals(this.label, chartElement.label) &&
        Objects.equals(this.max, chartElement.max) &&
        Objects.equals(this.median, chartElement.median) &&
        Objects.equals(this.min, chartElement.min) &&
        Objects.equals(this.outliers, chartElement.outliers) &&
        Objects.equals(this.png, chartElement.png) &&
        Objects.equals(this.points, chartElement.points) &&
        Objects.equals(this.radius, chartElement.radius) &&
        Objects.equals(this.thirdQuartile, chartElement.thirdQuartile) &&
        Objects.equals(this.title, chartElement.title) &&
        Objects.equals(this.type, chartElement.type) &&
        Objects.equals(this.value, chartElement.value) &&
        Objects.equals(this.xLabel, chartElement.xLabel) &&
        Objects.equals(this.yLabel, chartElement.yLabel)&&
        Objects.equals(this.additionalProperties, chartElement.additionalProperties);
  }

  @Override
  public int hashCode() {
    return Objects.hash(angle, firstQuartile, group, label, max, median, min, outliers, png, points, radius, thirdQuartile, title, type, value, xLabel, yLabel, additionalProperties);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class ChartElement {\n");
    sb.append("    angle: ").append(toIndentedString(angle)).append("\n");
    sb.append("    firstQuartile: ").append(toIndentedString(firstQuartile)).append("\n");
    sb.append("    group: ").append(toIndentedString(group)).append("\n");
    sb.append("    label: ").append(toIndentedString(label)).append("\n");
    sb.append("    max: ").append(toIndentedString(max)).append("\n");
    sb.append("    median: ").append(toIndentedString(median)).append("\n");
    sb.append("    min: ").append(toIndentedString(min)).append("\n");
    sb.append("    outliers: ").append(toIndentedString(outliers)).append("\n");
    sb.append("    png: ").append(toIndentedString(png)).append("\n");
    sb.append("    points: ").append(toIndentedString(points)).append("\n");
    sb.append("    radius: ").append(toIndentedString(radius)).append("\n");
    sb.append("    thirdQuartile: ").append(toIndentedString(thirdQuartile)).append("\n");
    sb.append("    title: ").append(toIndentedString(title)).append("\n");
    sb.append("    type: ").append(toIndentedString(type)).append("\n");
    sb.append("    value: ").append(toIndentedString(value)).append("\n");
    sb.append("    xLabel: ").append(toIndentedString(xLabel)).append("\n");
    sb.append("    yLabel: ").append(toIndentedString(yLabel)).append("\n");
    sb.append("    additionalProperties: ").append(toIndentedString(additionalProperties)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(Object o) {
    return o == null ? "null" : o.toString().replace("\n", "\n    ");
  }


  public static HashSet<String> openapiFields;
  public static HashSet<String> openapiRequiredFields;

  static {
    // a set of all properties/fields (JSON key names)
    openapiFields = new HashSet<String>(Arrays.asList("angle", "first_quartile", "group", "label", "max", "median", "min", "outliers", "png", "points", "radius", "third_quartile", "title", "type", "value", "x_label", "y_label"));

    // a set of required properties/fields (JSON key names)
    openapiRequiredFields = new HashSet<String>(0);
  }

  /**
   * Validates the JSON Element and throws an exception if issues found
   *
   * @param jsonElement JSON Element
   * @throws IOException if the JSON Element is invalid with respect to ChartElement
   */
  public static void validateJsonElement(JsonElement jsonElement) throws IOException {
      if (jsonElement == null) {
        if (!ChartElement.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
          throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "The required field(s) %s in ChartElement is not found in the empty JSON string", ChartElement.openapiRequiredFields.toString()));
        }
      }
        JsonObject jsonObj = jsonElement.getAsJsonObject();
      if ((jsonObj.get("group") != null && !jsonObj.get("group").isJsonNull()) && !jsonObj.get("group").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `group` to be a primitive type in the JSON string but got `%s`", jsonObj.get("group").toString()));
      }
      if ((jsonObj.get("label") != null && !jsonObj.get("label").isJsonNull()) && !jsonObj.get("label").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `label` to be a primitive type in the JSON string but got `%s`", jsonObj.get("label").toString()));
      }
      // ensure the optional json data is an array if present
      if (jsonObj.get("outliers") != null && !jsonObj.get("outliers").isJsonNull() && !jsonObj.get("outliers").isJsonArray()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `outliers` to be an array in the JSON string but got `%s`", jsonObj.get("outliers").toString()));
      }
      if ((jsonObj.get("png") != null && !jsonObj.get("png").isJsonNull()) && !jsonObj.get("png").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `png` to be a primitive type in the JSON string but got `%s`", jsonObj.get("png").toString()));
      }
      // ensure the optional json data is an array if present
      if (jsonObj.get("points") != null && !jsonObj.get("points").isJsonNull() && !jsonObj.get("points").isJsonArray()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `points` to be an array in the JSON string but got `%s`", jsonObj.get("points").toString()));
      }
      if ((jsonObj.get("title") != null && !jsonObj.get("title").isJsonNull()) && !jsonObj.get("title").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `title` to be a primitive type in the JSON string but got `%s`", jsonObj.get("title").toString()));
      }
      if ((jsonObj.get("type") != null && !jsonObj.get("type").isJsonNull()) && !jsonObj.get("type").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `type` to be a primitive type in the JSON string but got `%s`", jsonObj.get("type").toString()));
      }
      if ((jsonObj.get("value") != null && !jsonObj.get("value").isJsonNull()) && !jsonObj.get("value").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `value` to be a primitive type in the JSON string but got `%s`", jsonObj.get("value").toString()));
      }
      if ((jsonObj.get("x_label") != null && !jsonObj.get("x_label").isJsonNull()) && !jsonObj.get("x_label").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `x_label` to be a primitive type in the JSON string but got `%s`", jsonObj.get("x_label").toString()));
      }
      if ((jsonObj.get("y_label") != null && !jsonObj.get("y_label").isJsonNull()) && !jsonObj.get("y_label").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "Expected the field `y_label` to be a primitive type in the JSON string but got `%s`", jsonObj.get("y_label").toString()));
      }
  }

  public static class CustomTypeAdapterFactory implements TypeAdapterFactory {
    @SuppressWarnings("unchecked")
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
       if (!ChartElement.class.isAssignableFrom(type.getRawType())) {
         return null; // this class only serializes 'ChartElement' and its subtypes
       }
       final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
       final TypeAdapter<ChartElement> thisAdapter
                        = gson.getDelegateAdapter(this, TypeToken.get(ChartElement.class));

       return (TypeAdapter<T>) new TypeAdapter<ChartElement>() {
           @Override
           public void write(JsonWriter out, ChartElement value) throws IOException {
             JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
             obj.remove("additionalProperties");
             // serialize additional properties
             if (value.getAdditionalProperties() != null) {
               for (Map.Entry<String, Object> entry : value.getAdditionalProperties().entrySet()) {
                 if (entry.getValue() instanceof String)
                   obj.addProperty(entry.getKey(), (String) entry.getValue());
                 else if (entry.getValue() instanceof Number)
                   obj.addProperty(entry.getKey(), (Number) entry.getValue());
                 else if (entry.getValue() instanceof Boolean)
                   obj.addProperty(entry.getKey(), (Boolean) entry.getValue());
                 else if (entry.getValue() instanceof Character)
                   obj.addProperty(entry.getKey(), (Character) entry.getValue());
                 else {
                   JsonElement jsonElement = gson.toJsonTree(entry.getValue());
                   if (jsonElement.isJsonArray()) {
                     obj.add(entry.getKey(), jsonElement.getAsJsonArray());
                   } else {
                     obj.add(entry.getKey(), jsonElement.getAsJsonObject());
                   }
                 }
               }
             }
             elementAdapter.write(out, obj);
           }

           @Override
           public ChartElement read(JsonReader in) throws IOException {
             JsonElement jsonElement = elementAdapter.read(in);
             validateJsonElement(jsonElement);
             JsonObject jsonObj = jsonElement.getAsJsonObject();
             // store additional fields in the deserialized instance
             ChartElement instance = thisAdapter.fromJsonTree(jsonObj);
             for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
               if (!openapiFields.contains(entry.getKey())) {
                 if (entry.getValue().isJsonPrimitive()) { // primitive type
                   if (entry.getValue().getAsJsonPrimitive().isString())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsString());
                   else if (entry.getValue().getAsJsonPrimitive().isNumber())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsNumber());
                   else if (entry.getValue().getAsJsonPrimitive().isBoolean())
                     instance.putAdditionalProperty(entry.getKey(), entry.getValue().getAsBoolean());
                   else
                     throw new IllegalArgumentException(String.format(java.util.Locale.ROOT, "The field `%s` has unknown primitive type. Value: %s", entry.getKey(), entry.getValue().toString()));
                 } else if (entry.getValue().isJsonArray()) {
                     instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), List.class));
                 } else { // JSON object
                     instance.putAdditionalProperty(entry.getKey(), gson.fromJson(entry.getValue(), HashMap.class));
                 }
               }
             }
             return instance;
           }

       }.nullSafe();
    }
  }

  /**
   * Create an instance of ChartElement given an JSON string
   *
   * @param jsonString JSON string
   * @return An instance of ChartElement
   * @throws IOException if the JSON string is invalid with respect to ChartElement
   */
  public static ChartElement fromJson(String jsonString) throws IOException {
    return JSON.getGson().fromJson(jsonString, ChartElement.class);
  }

  /**
   * Convert an instance of ChartElement to an JSON string
   *
   * @return JSON string
   */
  public String toJson() {
    return JSON.getGson().toJson(this);
  }
}

