/*
 * Kubernetes
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: v1.21.1
 * 
 *
 * 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.cert.manager.models;

import java.util.Objects;
import java.util.Arrays;
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 io.cert.manager.models.V1CertificateStatusConditionsInner;
import java.io.IOException;
import java.time.OffsetDateTime;
import java.util.ArrayList;
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.lang.reflect.Type;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import io.kubernetes.client.openapi.JSON;

/**
 * Status of the Certificate. This is set and managed automatically. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
 */
@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2024-03-01T07:00:20.132973Z[Etc/UTC]")
public class V1CertificateStatus {
  public static final String SERIALIZED_NAME_CONDITIONS = "conditions";
  @SerializedName(SERIALIZED_NAME_CONDITIONS)
  private List<V1CertificateStatusConditionsInner> conditions;

  public static final String SERIALIZED_NAME_FAILED_ISSUANCE_ATTEMPTS = "failedIssuanceAttempts";
  @SerializedName(SERIALIZED_NAME_FAILED_ISSUANCE_ATTEMPTS)
  private Integer failedIssuanceAttempts;

  public static final String SERIALIZED_NAME_LAST_FAILURE_TIME = "lastFailureTime";
  @SerializedName(SERIALIZED_NAME_LAST_FAILURE_TIME)
  private OffsetDateTime lastFailureTime;

  public static final String SERIALIZED_NAME_NEXT_PRIVATE_KEY_SECRET_NAME = "nextPrivateKeySecretName";
  @SerializedName(SERIALIZED_NAME_NEXT_PRIVATE_KEY_SECRET_NAME)
  private String nextPrivateKeySecretName;

  public static final String SERIALIZED_NAME_NOT_AFTER = "notAfter";
  @SerializedName(SERIALIZED_NAME_NOT_AFTER)
  private OffsetDateTime notAfter;

  public static final String SERIALIZED_NAME_NOT_BEFORE = "notBefore";
  @SerializedName(SERIALIZED_NAME_NOT_BEFORE)
  private OffsetDateTime notBefore;

  public static final String SERIALIZED_NAME_RENEWAL_TIME = "renewalTime";
  @SerializedName(SERIALIZED_NAME_RENEWAL_TIME)
  private OffsetDateTime renewalTime;

  public static final String SERIALIZED_NAME_REVISION = "revision";
  @SerializedName(SERIALIZED_NAME_REVISION)
  private Integer revision;

  public V1CertificateStatus() {
  }

  public V1CertificateStatus conditions(List<V1CertificateStatusConditionsInner> conditions) {
    
    this.conditions = conditions;
    return this;
  }

  public V1CertificateStatus addConditionsItem(V1CertificateStatusConditionsInner conditionsItem) {
    if (this.conditions == null) {
      this.conditions = new ArrayList<>();
    }
    this.conditions.add(conditionsItem);
    return this;
  }

   /**
   * List of status conditions to indicate the status of certificates. Known condition types are &#x60;Ready&#x60; and &#x60;Issuing&#x60;.
   * @return conditions
  **/
  @jakarta.annotation.Nullable
  public List<V1CertificateStatusConditionsInner> getConditions() {
    return conditions;
  }


  public void setConditions(List<V1CertificateStatusConditionsInner> conditions) {
    this.conditions = conditions;
  }


  public V1CertificateStatus failedIssuanceAttempts(Integer failedIssuanceAttempts) {
    
    this.failedIssuanceAttempts = failedIssuanceAttempts;
    return this;
  }

   /**
   * The number of continuous failed issuance attempts up till now. This field gets removed (if set) on a successful issuance and gets set to 1 if unset and an issuance has failed. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1).
   * @return failedIssuanceAttempts
  **/
  @jakarta.annotation.Nullable
  public Integer getFailedIssuanceAttempts() {
    return failedIssuanceAttempts;
  }


  public void setFailedIssuanceAttempts(Integer failedIssuanceAttempts) {
    this.failedIssuanceAttempts = failedIssuanceAttempts;
  }


  public V1CertificateStatus lastFailureTime(OffsetDateTime lastFailureTime) {
    
    this.lastFailureTime = lastFailureTime;
    return this;
  }

   /**
   * LastFailureTime is set only if the lastest issuance for this Certificate failed and contains the time of the failure. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1). If the latest issuance has succeeded this field will be unset.
   * @return lastFailureTime
  **/
  @jakarta.annotation.Nullable
  public OffsetDateTime getLastFailureTime() {
    return lastFailureTime;
  }


  public void setLastFailureTime(OffsetDateTime lastFailureTime) {
    this.lastFailureTime = lastFailureTime;
  }


  public V1CertificateStatus nextPrivateKeySecretName(String nextPrivateKeySecretName) {
    
    this.nextPrivateKeySecretName = nextPrivateKeySecretName;
    return this;
  }

   /**
   * The name of the Secret resource containing the private key to be used for the next certificate iteration. The keymanager controller will automatically set this field if the &#x60;Issuing&#x60; condition is set to &#x60;True&#x60;. It will automatically unset this field when the Issuing condition is not set or False.
   * @return nextPrivateKeySecretName
  **/
  @jakarta.annotation.Nullable
  public String getNextPrivateKeySecretName() {
    return nextPrivateKeySecretName;
  }


  public void setNextPrivateKeySecretName(String nextPrivateKeySecretName) {
    this.nextPrivateKeySecretName = nextPrivateKeySecretName;
  }


  public V1CertificateStatus notAfter(OffsetDateTime notAfter) {
    
    this.notAfter = notAfter;
    return this;
  }

   /**
   * The expiration time of the certificate stored in the secret named by this resource in &#x60;spec.secretName&#x60;.
   * @return notAfter
  **/
  @jakarta.annotation.Nullable
  public OffsetDateTime getNotAfter() {
    return notAfter;
  }


  public void setNotAfter(OffsetDateTime notAfter) {
    this.notAfter = notAfter;
  }


  public V1CertificateStatus notBefore(OffsetDateTime notBefore) {
    
    this.notBefore = notBefore;
    return this;
  }

   /**
   * The time after which the certificate stored in the secret named by this resource in &#x60;spec.secretName&#x60; is valid.
   * @return notBefore
  **/
  @jakarta.annotation.Nullable
  public OffsetDateTime getNotBefore() {
    return notBefore;
  }


  public void setNotBefore(OffsetDateTime notBefore) {
    this.notBefore = notBefore;
  }


  public V1CertificateStatus renewalTime(OffsetDateTime renewalTime) {
    
    this.renewalTime = renewalTime;
    return this;
  }

   /**
   * RenewalTime is the time at which the certificate will be next renewed. If not set, no upcoming renewal is scheduled.
   * @return renewalTime
  **/
  @jakarta.annotation.Nullable
  public OffsetDateTime getRenewalTime() {
    return renewalTime;
  }


  public void setRenewalTime(OffsetDateTime renewalTime) {
    this.renewalTime = renewalTime;
  }


  public V1CertificateStatus revision(Integer revision) {
    
    this.revision = revision;
    return this;
  }

   /**
   * The current &#39;revision&#39; of the certificate as issued.   When a CertificateRequest resource is created, it will have the &#x60;cert-manager.io/certificate-revision&#x60; set to one greater than the current value of this field.   Upon issuance, this field will be set to the value of the annotation on the CertificateRequest resource used to issue the certificate.   Persisting the value on the CertificateRequest resource allows the certificates controller to know whether a request is part of an old issuance or if it is part of the ongoing revision&#39;s issuance by checking if the revision value in the annotation is greater than this field.
   * @return revision
  **/
  @jakarta.annotation.Nullable
  public Integer getRevision() {
    return revision;
  }


  public void setRevision(Integer revision) {
    this.revision = revision;
  }



  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    V1CertificateStatus v1CertificateStatus = (V1CertificateStatus) o;
    return Objects.equals(this.conditions, v1CertificateStatus.conditions) &&
        Objects.equals(this.failedIssuanceAttempts, v1CertificateStatus.failedIssuanceAttempts) &&
        Objects.equals(this.lastFailureTime, v1CertificateStatus.lastFailureTime) &&
        Objects.equals(this.nextPrivateKeySecretName, v1CertificateStatus.nextPrivateKeySecretName) &&
        Objects.equals(this.notAfter, v1CertificateStatus.notAfter) &&
        Objects.equals(this.notBefore, v1CertificateStatus.notBefore) &&
        Objects.equals(this.renewalTime, v1CertificateStatus.renewalTime) &&
        Objects.equals(this.revision, v1CertificateStatus.revision);
  }

  @Override
  public int hashCode() {
    return Objects.hash(conditions, failedIssuanceAttempts, lastFailureTime, nextPrivateKeySecretName, notAfter, notBefore, renewalTime, revision);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class V1CertificateStatus {\n");
    sb.append("    conditions: ").append(toIndentedString(conditions)).append("\n");
    sb.append("    failedIssuanceAttempts: ").append(toIndentedString(failedIssuanceAttempts)).append("\n");
    sb.append("    lastFailureTime: ").append(toIndentedString(lastFailureTime)).append("\n");
    sb.append("    nextPrivateKeySecretName: ").append(toIndentedString(nextPrivateKeySecretName)).append("\n");
    sb.append("    notAfter: ").append(toIndentedString(notAfter)).append("\n");
    sb.append("    notBefore: ").append(toIndentedString(notBefore)).append("\n");
    sb.append("    renewalTime: ").append(toIndentedString(renewalTime)).append("\n");
    sb.append("    revision: ").append(toIndentedString(revision)).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) {
    if (o == null) {
      return "null";
    }
    return 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>();
    openapiFields.add("conditions");
    openapiFields.add("failedIssuanceAttempts");
    openapiFields.add("lastFailureTime");
    openapiFields.add("nextPrivateKeySecretName");
    openapiFields.add("notAfter");
    openapiFields.add("notBefore");
    openapiFields.add("renewalTime");
    openapiFields.add("revision");

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

 /**
  * Validates the JSON Object and throws an exception if issues found
  *
  * @param jsonObj JSON Object
  * @throws IOException if the JSON Object is invalid with respect to V1CertificateStatus
  */
  public static void validateJsonObject(JsonObject jsonObj) throws IOException {
      if (jsonObj == null) {
        if (!V1CertificateStatus.openapiRequiredFields.isEmpty()) { // has required fields but JSON object is null
          throw new IllegalArgumentException(String.format("The required field(s) %s in V1CertificateStatus is not found in the empty JSON string", V1CertificateStatus.openapiRequiredFields.toString()));
        }
      }

      Set<Entry<String, JsonElement>> entries = jsonObj.entrySet();
      // check to see if the JSON string contains additional fields
      for (Entry<String, JsonElement> entry : entries) {
        if (!V1CertificateStatus.openapiFields.contains(entry.getKey())) {
          throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `V1CertificateStatus` properties. JSON: %s", entry.getKey(), jsonObj.toString()));
        }
      }
      if (jsonObj.get("conditions") != null && !jsonObj.get("conditions").isJsonNull()) {
        JsonArray jsonArrayconditions = jsonObj.getAsJsonArray("conditions");
        if (jsonArrayconditions != null) {
          // ensure the json data is an array
          if (!jsonObj.get("conditions").isJsonArray()) {
            throw new IllegalArgumentException(String.format("Expected the field `conditions` to be an array in the JSON string but got `%s`", jsonObj.get("conditions").toString()));
          }

          // validate the optional field `conditions` (array)
          for (int i = 0; i < jsonArrayconditions.size(); i++) {
            V1CertificateStatusConditionsInner.validateJsonObject(jsonArrayconditions.get(i).getAsJsonObject());
          };
        }
      }
      if ((jsonObj.get("nextPrivateKeySecretName") != null && !jsonObj.get("nextPrivateKeySecretName").isJsonNull()) && !jsonObj.get("nextPrivateKeySecretName").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format("Expected the field `nextPrivateKeySecretName` to be a primitive type in the JSON string but got `%s`", jsonObj.get("nextPrivateKeySecretName").toString()));
      }
  }

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

       return (TypeAdapter<T>) new TypeAdapter<V1CertificateStatus>() {
           @Override
           public void write(JsonWriter out, V1CertificateStatus value) throws IOException {
             JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject();
             elementAdapter.write(out, obj);
           }

           @Override
           public V1CertificateStatus read(JsonReader in) throws IOException {
             JsonObject jsonObj = elementAdapter.read(in).getAsJsonObject();
             validateJsonObject(jsonObj);
             return thisAdapter.fromJsonTree(jsonObj);
           }

       }.nullSafe();
    }
  }

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

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

