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

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;

/**
 * BlockDetailsModel
 */
@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 BlockDetailsModel {
  public static final String SERIALIZED_NAME_ACTUAL_TIMESTAMP = "actual_timestamp";
  @SerializedName(SERIALIZED_NAME_ACTUAL_TIMESTAMP)
  @javax.annotation.Nullable
  private Integer actualTimestamp;

  public static final String SERIALIZED_NAME_ALREADY_GENERATED_COINS = "already_generated_coins";
  @SerializedName(SERIALIZED_NAME_ALREADY_GENERATED_COINS)
  @javax.annotation.Nullable
  private String alreadyGeneratedCoins;

  public static final String SERIALIZED_NAME_BASE_REWARD = "base_reward";
  @SerializedName(SERIALIZED_NAME_BASE_REWARD)
  @javax.annotation.Nullable
  private Integer baseReward;

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

  public static final String SERIALIZED_NAME_BLOCK_CUMULATIVE_SIZE = "block_cumulative_size";
  @SerializedName(SERIALIZED_NAME_BLOCK_CUMULATIVE_SIZE)
  @javax.annotation.Nullable
  private Integer blockCumulativeSize;

  public static final String SERIALIZED_NAME_BLOCK_TSELF_SIZE = "block_tself_size";
  @SerializedName(SERIALIZED_NAME_BLOCK_TSELF_SIZE)
  @javax.annotation.Nullable
  private Integer blockTselfSize;

  public static final String SERIALIZED_NAME_CUMULATIVE_DIFF_ADJUSTED = "cumulative_diff_adjusted";
  @SerializedName(SERIALIZED_NAME_CUMULATIVE_DIFF_ADJUSTED)
  @javax.annotation.Nullable
  private String cumulativeDiffAdjusted;

  public static final String SERIALIZED_NAME_CUMULATIVE_DIFF_PRECISE = "cumulative_diff_precise";
  @SerializedName(SERIALIZED_NAME_CUMULATIVE_DIFF_PRECISE)
  @javax.annotation.Nullable
  private String cumulativeDiffPrecise;

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

  public static final String SERIALIZED_NAME_EFFECTIVE_FEE_MEDIAN = "effective_fee_median";
  @SerializedName(SERIALIZED_NAME_EFFECTIVE_FEE_MEDIAN)
  @javax.annotation.Nullable
  private Integer effectiveFeeMedian;

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

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

  public static final String SERIALIZED_NAME_IS_ORPHAN = "is_orphan";
  @SerializedName(SERIALIZED_NAME_IS_ORPHAN)
  @javax.annotation.Nullable
  private Boolean isOrphan;

  public static final String SERIALIZED_NAME_MINER_TEXT_INFO = "miner_text_info";
  @SerializedName(SERIALIZED_NAME_MINER_TEXT_INFO)
  @javax.annotation.Nullable
  private String minerTextInfo;

  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_PENALTY = "penalty";
  @SerializedName(SERIALIZED_NAME_PENALTY)
  @javax.annotation.Nullable
  private Integer penalty;

  public static final String SERIALIZED_NAME_POW_SEED = "pow_seed";
  @SerializedName(SERIALIZED_NAME_POW_SEED)
  @javax.annotation.Nullable
  private String powSeed;

  public static final String SERIALIZED_NAME_PREV_ID = "prev_id";
  @SerializedName(SERIALIZED_NAME_PREV_ID)
  @javax.annotation.Nullable
  private String prevId;

  public static final String SERIALIZED_NAME_SUMMARY_REWARD = "summary_reward";
  @SerializedName(SERIALIZED_NAME_SUMMARY_REWARD)
  @javax.annotation.Nullable
  private Integer summaryReward;

  public static final String SERIALIZED_NAME_THIS_BLOCK_FEE_MEDIAN = "this_block_fee_median";
  @SerializedName(SERIALIZED_NAME_THIS_BLOCK_FEE_MEDIAN)
  @javax.annotation.Nullable
  private Integer thisBlockFeeMedian;

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

  public static final String SERIALIZED_NAME_TOTAL_FEE = "total_fee";
  @SerializedName(SERIALIZED_NAME_TOTAL_FEE)
  @javax.annotation.Nullable
  private Integer totalFee;

  public static final String SERIALIZED_NAME_TOTAL_TXS_SIZE = "total_txs_size";
  @SerializedName(SERIALIZED_NAME_TOTAL_TXS_SIZE)
  @javax.annotation.Nullable
  private Integer totalTxsSize;

  public static final String SERIALIZED_NAME_TRANSACTIONS_DETAILS = "transactions_details";
  @SerializedName(SERIALIZED_NAME_TRANSACTIONS_DETAILS)
  @javax.annotation.Nullable
  private List<TransactionDetailsModel> transactionsDetails = new ArrayList<>();

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

  public BlockDetailsModel() {
  }

  public BlockDetailsModel actualTimestamp(@javax.annotation.Nullable Integer actualTimestamp) {
    this.actualTimestamp = actualTimestamp;
    return this;
  }

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

  public void setActualTimestamp(@javax.annotation.Nullable Integer actualTimestamp) {
    this.actualTimestamp = actualTimestamp;
  }


  public BlockDetailsModel alreadyGeneratedCoins(@javax.annotation.Nullable String alreadyGeneratedCoins) {
    this.alreadyGeneratedCoins = alreadyGeneratedCoins;
    return this;
  }

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

  public void setAlreadyGeneratedCoins(@javax.annotation.Nullable String alreadyGeneratedCoins) {
    this.alreadyGeneratedCoins = alreadyGeneratedCoins;
  }


  public BlockDetailsModel baseReward(@javax.annotation.Nullable Integer baseReward) {
    this.baseReward = baseReward;
    return this;
  }

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

  public void setBaseReward(@javax.annotation.Nullable Integer baseReward) {
    this.baseReward = baseReward;
  }


  public BlockDetailsModel 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 BlockDetailsModel blockCumulativeSize(@javax.annotation.Nullable Integer blockCumulativeSize) {
    this.blockCumulativeSize = blockCumulativeSize;
    return this;
  }

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

  public void setBlockCumulativeSize(@javax.annotation.Nullable Integer blockCumulativeSize) {
    this.blockCumulativeSize = blockCumulativeSize;
  }


  public BlockDetailsModel blockTselfSize(@javax.annotation.Nullable Integer blockTselfSize) {
    this.blockTselfSize = blockTselfSize;
    return this;
  }

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

  public void setBlockTselfSize(@javax.annotation.Nullable Integer blockTselfSize) {
    this.blockTselfSize = blockTselfSize;
  }


  public BlockDetailsModel cumulativeDiffAdjusted(@javax.annotation.Nullable String cumulativeDiffAdjusted) {
    this.cumulativeDiffAdjusted = cumulativeDiffAdjusted;
    return this;
  }

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

  public void setCumulativeDiffAdjusted(@javax.annotation.Nullable String cumulativeDiffAdjusted) {
    this.cumulativeDiffAdjusted = cumulativeDiffAdjusted;
  }


  public BlockDetailsModel cumulativeDiffPrecise(@javax.annotation.Nullable String cumulativeDiffPrecise) {
    this.cumulativeDiffPrecise = cumulativeDiffPrecise;
    return this;
  }

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

  public void setCumulativeDiffPrecise(@javax.annotation.Nullable String cumulativeDiffPrecise) {
    this.cumulativeDiffPrecise = cumulativeDiffPrecise;
  }


  public BlockDetailsModel difficulty(@javax.annotation.Nullable String difficulty) {
    this.difficulty = difficulty;
    return this;
  }

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

  public void setDifficulty(@javax.annotation.Nullable String difficulty) {
    this.difficulty = difficulty;
  }


  public BlockDetailsModel effectiveFeeMedian(@javax.annotation.Nullable Integer effectiveFeeMedian) {
    this.effectiveFeeMedian = effectiveFeeMedian;
    return this;
  }

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

  public void setEffectiveFeeMedian(@javax.annotation.Nullable Integer effectiveFeeMedian) {
    this.effectiveFeeMedian = effectiveFeeMedian;
  }


  public BlockDetailsModel height(@javax.annotation.Nullable Integer height) {
    this.height = height;
    return this;
  }

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

  public void setHeight(@javax.annotation.Nullable Integer height) {
    this.height = height;
  }


  public BlockDetailsModel 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 BlockDetailsModel isOrphan(@javax.annotation.Nullable Boolean isOrphan) {
    this.isOrphan = isOrphan;
    return this;
  }

  /**
   * Get isOrphan
   * @return isOrphan
   */
  @javax.annotation.Nullable
  public Boolean getIsOrphan() {
    return isOrphan;
  }

  public void setIsOrphan(@javax.annotation.Nullable Boolean isOrphan) {
    this.isOrphan = isOrphan;
  }


  public BlockDetailsModel minerTextInfo(@javax.annotation.Nullable String minerTextInfo) {
    this.minerTextInfo = minerTextInfo;
    return this;
  }

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

  public void setMinerTextInfo(@javax.annotation.Nullable String minerTextInfo) {
    this.minerTextInfo = minerTextInfo;
  }


  public BlockDetailsModel 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 BlockDetailsModel penalty(@javax.annotation.Nullable Integer penalty) {
    this.penalty = penalty;
    return this;
  }

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

  public void setPenalty(@javax.annotation.Nullable Integer penalty) {
    this.penalty = penalty;
  }


  public BlockDetailsModel powSeed(@javax.annotation.Nullable String powSeed) {
    this.powSeed = powSeed;
    return this;
  }

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

  public void setPowSeed(@javax.annotation.Nullable String powSeed) {
    this.powSeed = powSeed;
  }


  public BlockDetailsModel prevId(@javax.annotation.Nullable String prevId) {
    this.prevId = prevId;
    return this;
  }

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

  public void setPrevId(@javax.annotation.Nullable String prevId) {
    this.prevId = prevId;
  }


  public BlockDetailsModel summaryReward(@javax.annotation.Nullable Integer summaryReward) {
    this.summaryReward = summaryReward;
    return this;
  }

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

  public void setSummaryReward(@javax.annotation.Nullable Integer summaryReward) {
    this.summaryReward = summaryReward;
  }


  public BlockDetailsModel thisBlockFeeMedian(@javax.annotation.Nullable Integer thisBlockFeeMedian) {
    this.thisBlockFeeMedian = thisBlockFeeMedian;
    return this;
  }

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

  public void setThisBlockFeeMedian(@javax.annotation.Nullable Integer thisBlockFeeMedian) {
    this.thisBlockFeeMedian = thisBlockFeeMedian;
  }


  public BlockDetailsModel 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;
  }


  public BlockDetailsModel totalFee(@javax.annotation.Nullable Integer totalFee) {
    this.totalFee = totalFee;
    return this;
  }

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

  public void setTotalFee(@javax.annotation.Nullable Integer totalFee) {
    this.totalFee = totalFee;
  }


  public BlockDetailsModel totalTxsSize(@javax.annotation.Nullable Integer totalTxsSize) {
    this.totalTxsSize = totalTxsSize;
    return this;
  }

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

  public void setTotalTxsSize(@javax.annotation.Nullable Integer totalTxsSize) {
    this.totalTxsSize = totalTxsSize;
  }


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

  public BlockDetailsModel addTransactionsDetailsItem(TransactionDetailsModel transactionsDetailsItem) {
    if (this.transactionsDetails == null) {
      this.transactionsDetails = new ArrayList<>();
    }
    this.transactionsDetails.add(transactionsDetailsItem);
    return this;
  }

  /**
   * Get transactionsDetails
   * @return transactionsDetails
   */
  @javax.annotation.Nullable
  public List<TransactionDetailsModel> getTransactionsDetails() {
    return transactionsDetails;
  }

  public void setTransactionsDetails(@javax.annotation.Nullable List<TransactionDetailsModel> transactionsDetails) {
    this.transactionsDetails = transactionsDetails;
  }


  public BlockDetailsModel type(@javax.annotation.Nullable Integer type) {
    this.type = type;
    return this;
  }

  /**
   * Get type
   * minimum: 0
   * maximum: 4294967295
   * @return type
   */
  @javax.annotation.Nullable
  public Integer getType() {
    return type;
  }

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



  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    BlockDetailsModel blockDetailsModel = (BlockDetailsModel) o;
    return Objects.equals(this.actualTimestamp, blockDetailsModel.actualTimestamp) &&
        Objects.equals(this.alreadyGeneratedCoins, blockDetailsModel.alreadyGeneratedCoins) &&
        Objects.equals(this.baseReward, blockDetailsModel.baseReward) &&
        Objects.equals(this.blob, blockDetailsModel.blob) &&
        Objects.equals(this.blockCumulativeSize, blockDetailsModel.blockCumulativeSize) &&
        Objects.equals(this.blockTselfSize, blockDetailsModel.blockTselfSize) &&
        Objects.equals(this.cumulativeDiffAdjusted, blockDetailsModel.cumulativeDiffAdjusted) &&
        Objects.equals(this.cumulativeDiffPrecise, blockDetailsModel.cumulativeDiffPrecise) &&
        Objects.equals(this.difficulty, blockDetailsModel.difficulty) &&
        Objects.equals(this.effectiveFeeMedian, blockDetailsModel.effectiveFeeMedian) &&
        Objects.equals(this.height, blockDetailsModel.height) &&
        Objects.equals(this.id, blockDetailsModel.id) &&
        Objects.equals(this.isOrphan, blockDetailsModel.isOrphan) &&
        Objects.equals(this.minerTextInfo, blockDetailsModel.minerTextInfo) &&
        Objects.equals(this.objectInJson, blockDetailsModel.objectInJson) &&
        Objects.equals(this.penalty, blockDetailsModel.penalty) &&
        Objects.equals(this.powSeed, blockDetailsModel.powSeed) &&
        Objects.equals(this.prevId, blockDetailsModel.prevId) &&
        Objects.equals(this.summaryReward, blockDetailsModel.summaryReward) &&
        Objects.equals(this.thisBlockFeeMedian, blockDetailsModel.thisBlockFeeMedian) &&
        Objects.equals(this.timestamp, blockDetailsModel.timestamp) &&
        Objects.equals(this.totalFee, blockDetailsModel.totalFee) &&
        Objects.equals(this.totalTxsSize, blockDetailsModel.totalTxsSize) &&
        Objects.equals(this.transactionsDetails, blockDetailsModel.transactionsDetails) &&
        Objects.equals(this.type, blockDetailsModel.type);
  }

  @Override
  public int hashCode() {
    return Objects.hash(actualTimestamp, alreadyGeneratedCoins, baseReward, blob, blockCumulativeSize, blockTselfSize, cumulativeDiffAdjusted, cumulativeDiffPrecise, difficulty, effectiveFeeMedian, height, id, isOrphan, minerTextInfo, objectInJson, penalty, powSeed, prevId, summaryReward, thisBlockFeeMedian, timestamp, totalFee, totalTxsSize, transactionsDetails, type);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class BlockDetailsModel {\n");
    sb.append("    actualTimestamp: ").append(toIndentedString(actualTimestamp)).append("\n");
    sb.append("    alreadyGeneratedCoins: ").append(toIndentedString(alreadyGeneratedCoins)).append("\n");
    sb.append("    baseReward: ").append(toIndentedString(baseReward)).append("\n");
    sb.append("    blob: ").append(toIndentedString(blob)).append("\n");
    sb.append("    blockCumulativeSize: ").append(toIndentedString(blockCumulativeSize)).append("\n");
    sb.append("    blockTselfSize: ").append(toIndentedString(blockTselfSize)).append("\n");
    sb.append("    cumulativeDiffAdjusted: ").append(toIndentedString(cumulativeDiffAdjusted)).append("\n");
    sb.append("    cumulativeDiffPrecise: ").append(toIndentedString(cumulativeDiffPrecise)).append("\n");
    sb.append("    difficulty: ").append(toIndentedString(difficulty)).append("\n");
    sb.append("    effectiveFeeMedian: ").append(toIndentedString(effectiveFeeMedian)).append("\n");
    sb.append("    height: ").append(toIndentedString(height)).append("\n");
    sb.append("    id: ").append(toIndentedString(id)).append("\n");
    sb.append("    isOrphan: ").append(toIndentedString(isOrphan)).append("\n");
    sb.append("    minerTextInfo: ").append(toIndentedString(minerTextInfo)).append("\n");
    sb.append("    objectInJson: ").append(toIndentedString(objectInJson)).append("\n");
    sb.append("    penalty: ").append(toIndentedString(penalty)).append("\n");
    sb.append("    powSeed: ").append(toIndentedString(powSeed)).append("\n");
    sb.append("    prevId: ").append(toIndentedString(prevId)).append("\n");
    sb.append("    summaryReward: ").append(toIndentedString(summaryReward)).append("\n");
    sb.append("    thisBlockFeeMedian: ").append(toIndentedString(thisBlockFeeMedian)).append("\n");
    sb.append("    timestamp: ").append(toIndentedString(timestamp)).append("\n");
    sb.append("    totalFee: ").append(toIndentedString(totalFee)).append("\n");
    sb.append("    totalTxsSize: ").append(toIndentedString(totalTxsSize)).append("\n");
    sb.append("    transactionsDetails: ").append(toIndentedString(transactionsDetails)).append("\n");
    sb.append("    type: ").append(toIndentedString(type)).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("actual_timestamp", "already_generated_coins", "base_reward", "blob", "block_cumulative_size", "block_tself_size", "cumulative_diff_adjusted", "cumulative_diff_precise", "difficulty", "effective_fee_median", "height", "id", "is_orphan", "miner_text_info", "object_in_json", "penalty", "pow_seed", "prev_id", "summary_reward", "this_block_fee_median", "timestamp", "total_fee", "total_txs_size", "transactions_details", "type"));

    // 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 BlockDetailsModel
   */
  public static void validateJsonElement(JsonElement jsonElement) throws IOException {
      if (jsonElement == null) {
        if (!BlockDetailsModel.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null
          throw new IllegalArgumentException(String.format(Locale.ROOT, "The required field(s) %s in BlockDetailsModel is not found in the empty JSON string", BlockDetailsModel.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 (!BlockDetailsModel.openapiFields.contains(entry.getKey())) {
          throw new IllegalArgumentException(String.format(Locale.ROOT, "The field `%s` in the JSON string is not defined in the `BlockDetailsModel` properties. JSON: %s", entry.getKey(), jsonElement.toString()));
        }
      }
        JsonObject jsonObj = jsonElement.getAsJsonObject();
      if ((jsonObj.get("already_generated_coins") != null && !jsonObj.get("already_generated_coins").isJsonNull()) && !jsonObj.get("already_generated_coins").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `already_generated_coins` to be a primitive type in the JSON string but got `%s`", jsonObj.get("already_generated_coins").toString()));
      }
      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("cumulative_diff_adjusted") != null && !jsonObj.get("cumulative_diff_adjusted").isJsonNull()) && !jsonObj.get("cumulative_diff_adjusted").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `cumulative_diff_adjusted` to be a primitive type in the JSON string but got `%s`", jsonObj.get("cumulative_diff_adjusted").toString()));
      }
      if ((jsonObj.get("cumulative_diff_precise") != null && !jsonObj.get("cumulative_diff_precise").isJsonNull()) && !jsonObj.get("cumulative_diff_precise").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `cumulative_diff_precise` to be a primitive type in the JSON string but got `%s`", jsonObj.get("cumulative_diff_precise").toString()));
      }
      if ((jsonObj.get("difficulty") != null && !jsonObj.get("difficulty").isJsonNull()) && !jsonObj.get("difficulty").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `difficulty` to be a primitive type in the JSON string but got `%s`", jsonObj.get("difficulty").toString()));
      }
      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("miner_text_info") != null && !jsonObj.get("miner_text_info").isJsonNull()) && !jsonObj.get("miner_text_info").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `miner_text_info` to be a primitive type in the JSON string but got `%s`", jsonObj.get("miner_text_info").toString()));
      }
      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("pow_seed") != null && !jsonObj.get("pow_seed").isJsonNull()) && !jsonObj.get("pow_seed").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `pow_seed` to be a primitive type in the JSON string but got `%s`", jsonObj.get("pow_seed").toString()));
      }
      if ((jsonObj.get("prev_id") != null && !jsonObj.get("prev_id").isJsonNull()) && !jsonObj.get("prev_id").isJsonPrimitive()) {
        throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `prev_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prev_id").toString()));
      }
      if (jsonObj.get("transactions_details") != null && !jsonObj.get("transactions_details").isJsonNull()) {
        JsonArray jsonArraytransactionsDetails = jsonObj.getAsJsonArray("transactions_details");
        if (jsonArraytransactionsDetails != null) {
          // ensure the json data is an array
          if (!jsonObj.get("transactions_details").isJsonArray()) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "Expected the field `transactions_details` to be an array in the JSON string but got `%s`", jsonObj.get("transactions_details").toString()));
          }

          // validate the optional field `transactions_details` (array)
          for (int i = 0; i < jsonArraytransactionsDetails.size(); i++) {
            TransactionDetailsModel.validateJsonElement(jsonArraytransactionsDetails.get(i));
          };
        }
      }
  }

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

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

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

       }.nullSafe();
    }
  }

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

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

