/*
 * Lethean Blockchain API
 * OpenAPI for Lethean Blockchain
 *
 * The version of the OpenAPI document: 6.0.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 org.openapitools.client.model;

import java.util.Objects;
import java.util.Locale;
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.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.openapitools.client.model.TransactionAttachmentModel;
import org.openapitools.client.model.TransactionExtraModel;
import org.openapitools.client.model.TransactionInputModel;
import org.openapitools.client.model.TransactionOutputModel;

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 java.util.Locale;

import invalidPackageName.JSON;

/**
 * TransactionDetailsModel
 */
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", date = "2025-10-19T15:35:02.750468+01:00[Europe/London]", comments = "Generator version: 7.16.0")
public class TransactionDetailsModel {
  public static final String SERIALIZED_NAME_AMOUNT = "amount";
  @SerializedName(SERIALIZED_NAME_AMOUNT)
  @javax.annotation.Nullable
  private Integer amount;

  public static final String SERIALIZED_NAME_ATTACHMENTS = "attachments";
  @SerializedName(SERIALIZED_NAME_ATTACHMENTS)
  @javax.annotation.Nullable
  private List<TransactionAttachmentModel> attachments = new ArrayList<>();

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

  public static final String SERIALIZED_NAME_BLOB_SIZE = "blob_size";
  @SerializedName(SERIALIZED_NAME_BLOB_SIZE)
  @javax.annotation.Nullable
  private Integer blobSize;

  public static final String SERIALIZED_NAME_EXTRA = "extra";
  @SerializedName(SERIALIZED_NAME_EXTRA)
  @javax.annotation.Nullable
  private List<TransactionExtraModel> extra = new ArrayList<>();

  public static final String SERIALIZED_NAME_FEE = "fee";
  @SerializedName(SERIALIZED_NAME_FEE)
  @javax.annotation.Nullable
  private Integer fee;

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

  public static final String SERIALIZED_NAME_INS = "ins";
  @SerializedName(SERIALIZED_NAME_INS)
  @javax.annotation.Nullable
  private List<TransactionInputModel> ins = new ArrayList<>();

  public static final String SERIALIZED_NAME_KEEPER_BLOCK = "keeper_block";
  @SerializedName(SERIALIZED_NAME_KEEPER_BLOCK)
  @javax.annotation.Nullable
  private Long keeperBlock;

  public static final String SERIALIZED_NAME_OBJECT_IN_JSON = "object_in_json";
  @SerializedName(SERIALIZED_NAME_OBJECT_IN_JSON)
  @javax.annotation.Nullable
  private String objectInJson;

  public static final String SERIALIZED_NAME_OUTS = "outs";
  @SerializedName(SERIALIZED_NAME_OUTS)
  @javax.annotation.Nullable
  private List<TransactionOutputModel> outs = new ArrayList<>();

  public static final String SERIALIZED_NAME_PUB_KEY = "pub_key";
  @SerializedName(SERIALIZED_NAME_PUB_KEY)
  @javax.annotation.Nullable
  private String pubKey;

  public static final String SERIALIZED_NAME_TIMESTAMP = "timestamp";
  @SerializedName(SERIALIZED_NAME_TIMESTAMP)
  @javax.annotation.Nullable
  private Integer timestamp;

  public TransactionDetailsModel() {
  }

  public TransactionDetailsModel amount(@javax.annotation.Nullable Integer amount) {
    this.amount = amount;
    return this;
  }

  /**
   * Get amount
   * @return amount
   */
  @javax.annotation.Nullable
  public Integer getAmount() {
    return amount;
  }

  public void setAmount(@javax.annotation.Nullable Integer amount) {
    this.amount = amount;
  }


  public TransactionDetailsModel attachments(@javax.annotation.Nullable List<TransactionAttachmentModel> attachments) {
    this.attachments = attachments;
    return this;
  }

  public TransactionDetailsModel addAttachmentsItem(TransactionAttachmentModel attachmentsItem) {
    if (this.attachments == null) {
      this.attachments = new ArrayList<>();
    }
    this.attachments.add(attachmentsItem);
    return this;
  }

  /**
   * Get attachments
   * @return attachments
   */
  @javax.annotation.Nullable
  public List<TransactionAttachmentModel> getAttachments() {
    return attachments;
  }

  public void setAttachments(@javax.annotation.Nullable List<TransactionAttachmentModel> attachments) {
    this.attachments = attachments;
  }


  public TransactionDetailsModel blob(@javax.annotation.Nullable String blob) {
    this.blob = blob;
    return this;
  }

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

  public void setBlob(@javax.annotation.Nullable String blob) {
    this.blob = blob;
  }


  public TransactionDetailsModel blobSize(@javax.annotation.Nullable Integer blobSize) {
    this.blobSize = blobSize;
    return this;
  }

  /**
   * Get blobSize
   * @return blobSize
   */
  @javax.annotation.Nullable
  public Integer getBlobSize() {
    return blobSize;
  }

  public void setBlobSize(@javax.annotation.Nullable Integer blobSize) {
    this.blobSize = blobSize;
  }


  public TransactionDetailsModel extra(@javax.annotation.Nullable List<TransactionExtraModel> extra) {
    this.extra = extra;
    return this;
  }

  public TransactionDetailsModel addExtraItem(TransactionExtraModel extraItem) {
    if (this.extra == null) {
      this.extra = new ArrayList<>();
    }
    this.extra.add(extraItem);
    return this;
  }

  /**
   * Get extra
   * @return extra
   */
  @javax.annotation.Nullable
  public List<TransactionExtraModel> getExtra() {
    return extra;
  }

  public void setExtra(@javax.annotation.Nullable List<TransactionExtraModel> extra) {
    this.extra = extra;
  }


  public TransactionDetailsModel fee(@javax.annotation.Nullable Integer fee) {
    this.fee = fee;
    return this;
  }

  /**
   * Get fee
   * @return fee
   */
  @javax.annotation.Nullable
  public Integer getFee() {
    return fee;
  }

  public void setFee(@javax.annotation.Nullable Integer fee) {
    this.fee = fee;
  }


  public TransactionDetailsModel id(@javax.annotation.Nullable String id) {
    this.id = id;
    return this;
  }

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

  public void setId(@javax.annotation.Nullable String id) {
    this.id = id;
  }


  public TransactionDetailsModel ins(@javax.annotation.Nullable List<TransactionInputModel> ins) {
    this.ins = ins;
    return this;
  }

  public TransactionDetailsModel addInsItem(TransactionInputModel insItem) {
    if (this.ins == null) {
      this.ins = new ArrayList<>();
    }
    this.ins.add(insItem);
    return this;
  }

  /**
   * Get ins
   * @return ins
   */
  @javax.annotation.Nullable
  public List<TransactionInputModel> getIns() {
    return ins;
  }

  public void setIns(@javax.annotation.Nullable List<TransactionInputModel> ins) {
    this.ins = ins;
  }


  public TransactionDetailsModel keeperBlock(@javax.annotation.Nullable Long keeperBlock) {
    this.keeperBlock = keeperBlock;
    return this;
  }

  /**
   * Get keeperBlock
   * @return keeperBlock
   */
  @javax.annotation.Nullable
  public Long getKeeperBlock() {
    return keeperBlock;
  }

  public void setKeeperBlock(@javax.annotation.Nullable Long keeperBlock) {
    this.keeperBlock = keeperBlock;
  }


  public TransactionDetailsModel objectInJson(@javax.annotation.Nullable String objectInJson) {
    this.objectInJson = objectInJson;
    return this;
  }

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

  public void setObjectInJson(@javax.annotation.Nullable String objectInJson) {
    this.objectInJson = objectInJson;
  }


  public TransactionDetailsModel outs(@javax.annotation.Nullable List<TransactionOutputModel> outs) {
    this.outs = outs;
    return this;
  }

  public TransactionDetailsModel addOutsItem(TransactionOutputModel outsItem) {
    if (this.outs == null) {
      this.outs = new ArrayList<>();
    }
    this.outs.add(outsItem);
    return this;
  }

  /**
   * Get outs
   * @return outs
   */
  @javax.annotation.Nullable
  public List<TransactionOutputModel> getOuts() {
    return outs;
  }

  public void setOuts(@javax.annotation.Nullable List<TransactionOutputModel> outs) {
    this.outs = outs;
  }


  public TransactionDetailsModel pubKey(@javax.annotation.Nullable String pubKey) {
    this.pubKey = pubKey;
    return this;
  }

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

  public void setPubKey(@javax.annotation.Nullable String pubKey) {
    this.pubKey = pubKey;
  }


  public TransactionDetailsModel timestamp(@javax.annotation.Nullable Integer timestamp) {
    this.timestamp = timestamp;
    return this;
  }

  /**
   * Get timestamp
   * @return timestamp
   */
  @javax.annotation.Nullable
  public Integer getTimestamp() {
    return timestamp;
  }

  public void setTimestamp(@javax.annotation.Nullable Integer timestamp) {
    this.timestamp = timestamp;
  }



  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    TransactionDetailsModel transactionDetailsModel = (TransactionDetailsModel) o;
    return Objects.equals(this.amount, transactionDetailsModel.amount) &&
        Objects.equals(this.attachments, transactionDetailsModel.attachments) &&
        Objects.equals(this.blob, transactionDetailsModel.blob) &&
        Objects.equals(this.blobSize, transactionDetailsModel.blobSize) &&
        Objects.equals(this.extra, transactionDetailsModel.extra) &&
        Objects.equals(this.fee, transactionDetailsModel.fee) &&
        Objects.equals(this.id, transactionDetailsModel.id) &&
        Objects.equals(this.ins, transactionDetailsModel.ins) &&
        Objects.equals(this.keeperBlock, transactionDetailsModel.keeperBlock) &&
        Objects.equals(this.objectInJson, transactionDetailsModel.objectInJson) &&
        Objects.equals(this.outs, transactionDetailsModel.outs) &&
        Objects.equals(this.pubKey, transactionDetailsModel.pubKey) &&
        Objects.equals(this.timestamp, transactionDetailsModel.timestamp);
  }

  @Override
  public int hashCode() {
    return Objects.hash(amount, attachments, blob, blobSize, extra, fee, id, ins, keeperBlock, objectInJson, outs, pubKey, timestamp);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class TransactionDetailsModel {\n");
    sb.append("    amount: ").append(toIndentedString(amount)).append("\n");
    sb.append("    attachments: ").append(toIndentedString(attachments)).append("\n");
    sb.append("    blob: ").append(toIndentedString(blob)).append("\n");
    sb.append("    blobSize: ").append(toIndentedString(blobSize)).append("\n");
    sb.append("    extra: ").append(toIndentedString(extra)).append("\n");
    sb.append("    fee: ").append(toIndentedString(fee)).append("\n");
    sb.append("    id: ").append(toIndentedString(id)).append("\n");
    sb.append("    ins: ").append(toIndentedString(ins)).append("\n");
    sb.append("    keeperBlock: ").append(toIndentedString(keeperBlock)).append("\n");
    sb.append("    objectInJson: ").append(toIndentedString(objectInJson)).append("\n");
    sb.append("    outs: ").append(toIndentedString(outs)).append("\n");
    sb.append("    pubKey: ").append(toIndentedString(pubKey)).append("\n");
    sb.append("    timestamp: ").append(toIndentedString(timestamp)).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>(Arrays.asList("amount", "attachments", "blob", "blob_size", "extra", "fee", "id", "ins", "keeper_block", "object_in_json", "outs", "pub_key", "timestamp"));

    // 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 TransactionDetailsModel
   */
  public static void validateJsonElement(JsonElement jsonElement) throws IOException {
      if (jsonElement == null) {
        if (!TransactionDetailsModel.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
          throw new IllegalArgumentException(String.format(Locale.ROOT, "The required field(s) %s in TransactionDetailsModel is not found in the empty JSON string", TransactionDetailsModel.openapiRequiredFields.toString()));
        }
      }

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

          // validate the optional field `attachments` (array)
          for (int i = 0; i < jsonArrayattachments.size(); i++) {
            TransactionAttachmentModel.validateJsonElement(jsonArrayattachments.get(i));
          };
        }
      }
      if ((jsonObj.get("blob") != null && !jsonObj.get("blob").isJsonNull()) && !jsonObj.get("blob").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `blob` to be a primitive type in the JSON string but got `%s`", jsonObj.get("blob").toString()));
      }
      if (jsonObj.get("extra") != null && !jsonObj.get("extra").isJsonNull()) {
        JsonArray jsonArrayextra = jsonObj.getAsJsonArray("extra");
        if (jsonArrayextra != null) {
          // ensure the json data is an array
          if (!jsonObj.get("extra").isJsonArray()) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `extra` to be an array in the JSON string but got `%s`", jsonObj.get("extra").toString()));
          }

          // validate the optional field `extra` (array)
          for (int i = 0; i < jsonArrayextra.size(); i++) {
            TransactionExtraModel.validateJsonElement(jsonArrayextra.get(i));
          };
        }
      }
      if ((jsonObj.get("id") != null && !jsonObj.get("id").isJsonNull()) && !jsonObj.get("id").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString()));
      }
      if (jsonObj.get("ins") != null && !jsonObj.get("ins").isJsonNull()) {
        JsonArray jsonArrayins = jsonObj.getAsJsonArray("ins");
        if (jsonArrayins != null) {
          // ensure the json data is an array
          if (!jsonObj.get("ins").isJsonArray()) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `ins` to be an array in the JSON string but got `%s`", jsonObj.get("ins").toString()));
          }

          // validate the optional field `ins` (array)
          for (int i = 0; i < jsonArrayins.size(); i++) {
            TransactionInputModel.validateJsonElement(jsonArrayins.get(i));
          };
        }
      }
      if ((jsonObj.get("object_in_json") != null && !jsonObj.get("object_in_json").isJsonNull()) && !jsonObj.get("object_in_json").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `object_in_json` to be a primitive type in the JSON string but got `%s`", jsonObj.get("object_in_json").toString()));
      }
      if (jsonObj.get("outs") != null && !jsonObj.get("outs").isJsonNull()) {
        JsonArray jsonArrayouts = jsonObj.getAsJsonArray("outs");
        if (jsonArrayouts != null) {
          // ensure the json data is an array
          if (!jsonObj.get("outs").isJsonArray()) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `outs` to be an array in the JSON string but got `%s`", jsonObj.get("outs").toString()));
          }

          // validate the optional field `outs` (array)
          for (int i = 0; i < jsonArrayouts.size(); i++) {
            TransactionOutputModel.validateJsonElement(jsonArrayouts.get(i));
          };
        }
      }
      if ((jsonObj.get("pub_key") != null && !jsonObj.get("pub_key").isJsonNull()) && !jsonObj.get("pub_key").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `pub_key` to be a primitive type in the JSON string but got `%s`", jsonObj.get("pub_key").toString()));
      }
  }

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

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

           @Override
           public TransactionDetailsModel read(JsonReader in) throws IOException {
             JsonElement jsonElement = elementAdapter.read(in);
             validateJsonElement(jsonElement);
             return thisAdapter.fromJsonTree(jsonElement);
           }

       }.nullSafe();
    }
  }

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

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

