package info.blockchain.api.exchangerates;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import info.blockchain.api.APIException;
import info.blockchain.api.HttpClient;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * This class reflects the functionality documented
 * at https://blockchain.info/api/exchange_rates_api. It allows users to fetch the latest
 * ticker data and convert amounts between BTC and fiat currencies.
 */
public class ExchangeRates {
    /**
     * Gets the price ticker from https://blockchain.info/ticker
     *
     * @return A map of currencies where the key is a 3-letter currency symbol and the
     * value is the `Currency` class
     * @throws APIException If the server returns an error
     */
    public static Map<String, Currency> getTicker () throws APIException, IOException {
        return getTicker(null);
    }

    /**
     * Gets the price ticker from https://blockchain.info/ticker
     *
     * @param apiCode Blockchain.info API code (optional, nullable)
     * @return A map of currencies where the key is a 3-letter currency symbol and the
     * value is the `Currency` class
     * @throws APIException If the server returns an error
     */
    public static Map<String, Currency> getTicker (String apiCode) throws APIException, IOException {
        Map<String, String> params = new HashMap<String, String>();
        if (apiCode != null) {
            params.put("api_code", apiCode);
        }

        String response = HttpClient.getInstance().get("ticker", params);
        JsonObject ticker = new JsonParser().parse(response).getAsJsonObject();

        Map<String, Currency> resultMap = new HashMap<String, Currency>();
        for (Entry<String, JsonElement> ccyKVP : ticker.entrySet()) {
            JsonObject ccy = ccyKVP.getValue().getAsJsonObject();
            Currency currency = new Currency(ccy.get("buy").getAsDouble(), ccy.get("sell").getAsDouble(), ccy.get("last").getAsDouble(), ccy.get("15m").getAsDouble(), ccy.get("symbol").getAsString());

            resultMap.put(ccyKVP.getKey(), currency);
        }

        return resultMap;
    }

    /**
     * Converts x value in the provided currency to BTC.
     *
     * @param currency Currency code
     * @param value    Value to convert
     * @return Converted value in BTC
     * @throws APIException If the server returns an error
     */
    public static BigDecimal toBTC (String currency, BigDecimal value) throws APIException, IOException {
        return toBTC(currency, value, null);
    }

    /**
     * Converts x value in the provided currency to BTC.
     *
     * @param currency Currency code
     * @param value    Value to convert
     * @param apiCode  Blockchain.info API code (optional, nullable)
     * @return Converted value in BTC
     * @throws APIException If the server returns an error
     */
    public static BigDecimal toBTC (String currency, BigDecimal value, String apiCode) throws APIException, IOException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("currency", currency);
        params.put("value", String.valueOf(value));
        if (apiCode != null) {
            params.put("api_code", apiCode);
        }

        String response = HttpClient.getInstance().get("tobtc", params);
        return new BigDecimal(response);
    }
}

@@ -609,278 +609,100 @@
 s %7B%0A
-    /**%0A     * Gets the price ticker from https://blockchain.info/ticker%0A     *%0A     * @return A map of currencies where the key is a 3-letter currency symbol and the%0A     * value is the %60Currency%60 class%0A     * @throws APIException If the server returns an error%0A 
+%0A    private final String apiCode;%0A%0A    public ExchangeRates () %7B%0A        this(null);%0A
     
-*/
+%7D%0A
 %0A   
@@ -713,115 +713,71 @@
 lic 
-static Map%3CString, Currency%3E getTicker () throws APIException, IOException %7B%0A        return getTicker(null)
+ExchangeRates (String apiCode) %7B%0A        this.apiCode = apiCode
 ;%0A  
@@ -865,76 +865,8 @@
   *%0A
-     * @param apiCode Blockchain.info API code (optional, nullable)%0A
     
@@ -1063,23 +1063,16 @@
  public 
-static 
 Map%3CStri
@@ -1096,30 +1096,16 @@
 Ticker (
-String apiCode
 ) throws
@@ -2211,39 +2211,32 @@
   */%0A    public 
-static 
 BigDecimal toBTC
@@ -2319,29 +2319,96 @@
     
-return toBTC(
+Map%3CString, String%3E params = new HashMap%3CString, String%3E();%0A        params.put(%22
 currency
 , va
@@ -2407,21 +2407,272 @@
 ency
+%22
 , 
+currency);%0A        params.put(%22
 value
+%22
 , 
-null
+String.valueOf(value));%0A        if (apiCode != null) %7B%0A            params.put(%22api_code%22, apiCode);%0A        %7D%0A%0A        String response = HttpClient.getInstance().get(%22tobtc%22, params);%0A        return new BigDecimal(response
 );%0A 
@@ -2704,32 +2704,39 @@
 erts x value in 
+BTC to 
 the provided cur
@@ -2732,39 +2732,32 @@
 rovided currency
- to BTC
 .%0A     *%0A     * 
@@ -2830,77 +2830,8 @@
 ert%0A
-     * @param apiCode  Blockchain.info API code (optional, nullable)%0A
     
@@ -2852,35 +2852,53 @@
 verted value in 
-BTC
+the provided currency
 %0A     * @throws 
@@ -2964,15 +2964,8 @@
 lic 
-static 
 BigD
@@ -2965,35 +2965,36 @@
 ic BigDecimal to
-BTC
+Fiat
  (String currenc
@@ -3016,24 +3016,8 @@
 alue
-, String apiCode
 ) th
@@ -3199,35 +3199,113 @@
 ng.valueOf(value
-));
+.multiply(BigDecimal.valueOf(100000000L)))); // The endpoint is expecting satoshi
 %0A        if (api
@@ -3424,34 +3424,36 @@
 Instance().get(%22
-to
+from
 btc%22, params);%0A 
@@ -3498,10 +3498,11 @@
 ;%0A    %7D%0A
+%0A
 %7D%0A

Update Wallet API: exchanges