package org.knowm.xchange.coinmarketcap.pro.v1.dto.marketdata;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.knowm.xchange.utils.jackson.ISO8601DateDeserializer;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

public final class CmcTicker {

  private final String symbol;
  private final BigDecimal circulatingSupply;
  private final Date lastUpdated;
  private final BigDecimal totalSupply;
  private final int cmcRank;
  private final CmcPlatform platform;
  private final List<String> tags;
  private final Date dateAdded;
  private final Map<String, CmcQuote> quoteData;
  private final BigDecimal numMarketPairs;
  private final String name;
  private final BigDecimal maxSupply;
  private final int id;
  private final String slug;

  public CmcTicker(
      @JsonProperty("symbol") String symbol,
      @JsonProperty("circulating_supply") BigDecimal circulatingSupply,
      @JsonProperty("last_updated") @JsonDeserialize(using = ISO8601DateDeserializer.class)
          Date lastUpdated,
      @JsonProperty("total_supply") BigDecimal totalSupply,
      @JsonProperty("cmc_rank") int cmcRank,
      @JsonProperty("platform") CmcPlatform platform,
      @JsonProperty("tags") List<String> tags,
      @JsonProperty("date_added") @JsonDeserialize(using = ISO8601DateDeserializer.class)
          Date dateAdded,
      @JsonProperty("quote") @JsonDeserialize(using = CoinMarketCapQuoteDeserializer.class)
          Map<String, CmcQuote> quoteData,
      @JsonProperty("num_market_pairs") BigDecimal numMarketPairs,
      @JsonProperty("name") String name,
      @JsonProperty("max_supply") BigDecimal maxSupply,
      @JsonProperty("id") int id,
      @JsonProperty("slug") String slug) {

    this.symbol = symbol;
    this.circulatingSupply = circulatingSupply;
    this.lastUpdated = lastUpdated;
    this.totalSupply = totalSupply;
    this.cmcRank = cmcRank;
    this.platform = platform;
    this.tags = tags;
    this.dateAdded = dateAdded;
    this.quoteData = quoteData;
    this.numMarketPairs = numMarketPairs;
    this.name = name;
    this.maxSupply = maxSupply;
    this.id = id;
    this.slug = slug;
  }

  public String getSymbol() {
    return symbol;
  }

  public BigDecimal getCirculatingSupply() {
    return circulatingSupply;
  }

  public Date getLastUpdated() {
    return lastUpdated;
  }

  public BigDecimal getTotalSupply() {
    return totalSupply;
  }

  public int getCmcRank() {
    return cmcRank;
  }

  public CmcPlatform getPlatform() {
    return platform;
  }

  public List<String> getTags() {
    return tags;
  }

  public Date getDateAdded() {
    return dateAdded;
  }

  public Map<String, CmcQuote> getQuote() {
    return quoteData;
  }

  public BigDecimal getNumMarketPairs() {
    return numMarketPairs;
  }

  public String getName() {
    return name;
  }

  public BigDecimal getMaxSupply() {
    return maxSupply;
  }

  public int getId() {
    return id;
  }

  public String getSlug() {
    return slug;
  }

  @Override
  public String toString() {
    return "CmcTicker{"
        + "symbol = '"
        + symbol
        + '\''
        + ",circulating_supply = '"
        + circulatingSupply
        + '\''
        + ",last_updated = '"
        + lastUpdated
        + '\''
        + ",total_supply = '"
        + totalSupply
        + '\''
        + ",cmc_rank = '"
        + cmcRank
        + '\''
        + ",platform = '"
        + platform
        + '\''
        + ",tags = '"
        + tags
        + '\''
        + ",date_added = '"
        + dateAdded
        + '\''
        + ",quote = '"
        + quoteData
        + '\''
        + ",num_market_pairs = '"
        + numMarketPairs
        + '\''
        + ",name = '"
        + name
        + '\''
        + ",max_supply = '"
        + maxSupply
        + '\''
        + ",id = '"
        + id
        + '\''
        + ",slug = '"
        + slug
        + '\''
        + "}";
  }

  public static class CoinMarketCapQuoteDeserializer
      extends JsonDeserializer<Map<String, CmcQuote>> {

    @Override
    public Map<String, CmcQuote> deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException {
      JsonNode jsonNode = jp.getCodec().readTree(jp);
      return deserializeFromNode(jsonNode);
    }

    static Map<String, CmcQuote> deserializeFromNode(JsonNode jsonNode) throws IOException {
      Iterator<Map.Entry<String, JsonNode>> iterator = jsonNode.fields();
      Map<String, CmcQuote> quoteData = new HashMap<>();
      ObjectMapper mapper = new ObjectMapper();
      while (iterator.hasNext()) {
        Map.Entry<String, JsonNode> entry = iterator.next();
        CmcQuote quote = mapper.readValue(entry.getValue().toString(), CmcQuote.class);
        quoteData.put(entry.getKey(), quote);
      }
      return quoteData;
    }
  }
}

@@ -115,272 +115,8 @@
 ty;%0A
-import com.fasterxml.jackson.core.JsonParser;%0Aimport com.fasterxml.jackson.databind.DeserializationContext;%0Aimport com.fasterxml.jackson.databind.JsonDeserializer;%0Aimport com.fasterxml.jackson.databind.JsonNode;%0Aimport com.fasterxml.jackson.databind.ObjectMapper;%0A
 impo
@@ -177,16 +177,16 @@
 ialize;%0A
+
 import o
@@ -246,36 +246,8 @@
 r;%0A%0A
-import java.io.IOException;%0A
 impo
@@ -292,9 +292,57 @@
 til.
-*
+Date;%0Aimport java.util.List;%0Aimport java.util.Map
 ;%0A%0Ap
@@ -1481,81 +1481,8 @@
 te%22)
- @JsonDeserialize(using = CoinMarketCapQuoteDeserializer.class)%0A         
  Map
@@ -3936,32 +3936,32 @@
 %0A        + '%5C''%0A
+
         + %22%7D%22;%0A 
@@ -3966,899 +3966,7 @@
 %0A  %7D
-%0A%0A  public static class CoinMarketCapQuoteDeserializer%0A      extends JsonDeserializer%3CMap%3CString, CmcQuote%3E%3E %7B%0A%0A    @Override%0A    public Map%3CString, CmcQuote%3E deserialize(JsonParser jp, DeserializationContext ctxt)%0A        throws IOException %7B%0A      JsonNode jsonNode = jp.getCodec().readTree(jp);%0A      return deserializeFromNode(jsonNode);%0A    %7D%0A%0A    static Map%3CString, CmcQuote%3E deserializeFromNode(JsonNode jsonNode) throws IOException %7B%0A      Iterator%3CMap.Entry%3CString, JsonNode%3E%3E iterator = jsonNode.fields();%0A      Map%3CString, CmcQuote%3E quoteData = new HashMap%3C%3E();%0A      ObjectMapper mapper = new ObjectMapper();%0A      while (iterator.hasNext()) %7B%0A        Map.Entry%3CString, JsonNode%3E entry = iterator.next();%0A        CmcQuote quote = mapper.readValue(entry.getValue().toString(), CmcQuote.class);%0A        quoteData.put(entry.getKey(), quote);%0A      %7D%0A      return quoteData;%0A    %7D%0A  %7D
 %0A%7D%0A

Remove unnecessary deserializer