// Path: src/main/java/com/github/vedenin/codingchallenge/exceptions/RestClientException.java
// public class RestClientException extends RuntimeException {
//     public RestClientException() {
//     }
// 
//     public RestClientException(String message) {
//         super(message);
//     }
// 
//     public RestClientException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public RestClientException(Throwable cause) {
//         super(cause);
//     }
// 
//     public RestClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/restclient/RestClient.java
// public interface RestClient {
//     BigDecimal getCurrentExchangeRates(CurrencyEnum currecnyFrom, CurrencyEnum currecnyTo);
//     BigDecimal getHistoricalExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, Calendar calendar);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/common/CurrencyEnum.java
// public enum CurrencyEnum {
//     EUR("EUR", "Euro (EUR)"),
//     USD("USD", "US Dollar (USD)"),
//     GBP("GBP", "British Pound (GBP)"),
//     NZD("NZD", "New Zealand Dollar (NZD)"),
//     AUD("AUD", "Australian Dollar (AUD)"),
//     JPY("JPY", "Japanese Yen (JPY)"),
//     HUF("HUF", "Hungarian Forint (HUF)"),
//     RUB("RUB", "Russian Ruble (RUB)"),
//     PLN("PLN", "Polish Zloty (PLN)");
//     private final String code;
//     private final String description;
// 
//     CurrencyEnum(String code, String description) {
//         this.code = code;
//         this.description = description;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }


import com.github.vedenin.codingchallenge.exceptions.RestClientException;
import com.github.vedenin.codingchallenge.restclient.RestClient;
import com.github.vedenin.codingchallenge.common.CurrencyEnum;
import org.springframework.stereotype.Service;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
import java.math.BigDecimal;
import java.util.Calendar;
import static java.math.BigDecimal.ROUND_FLOOR;
package com.github.vedenin.codingchallenge.restclient.impl.currencylayer;




/**
 * Created by slava on 04.02.17.
 */
@Service("CurrencyLayer")
public class CurrencyLayerRestClient implements RestClient {
    private final static String URL_LAST = "http://www.apilayer.net/api/live?format=1";
    private final static String URL_HISTORY = "http://apilayer.net/api/historical?date=";
    private final static String API_ID = "f7e5948888d41713110273b47c682db0";
    private final static String API_ID_PRM = "&access_key=";
    private static final String ERROR_WHILE_GATHERING_INFORMATION = "Error while gathering information from CurrencyLayer services";


    public BigDecimal getCurrentExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo) {
        return getExchangeRates(currencyFrom, currencyTo, getCurrentRates());
    }

    public BigDecimal getHistoricalExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, Calendar calendar) {
        return getExchangeRates(currencyFrom, currencyTo, getHistoricalRates(calendar));
    }

    private BigDecimal getExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, CurrencyLayerRatesContainer rates) {
        BigDecimal currencyFromRate = getRates(currencyFrom, rates);
        BigDecimal currencyToRate = getRates(currencyTo, rates);
        return currencyToRate.divide(currencyFromRate, 20, ROUND_FLOOR);
    }

    public CurrencyLayerRatesContainer getCurrentRates() {
        return getEntity(URL_LAST, API_ID, CurrencyLayerRatesContainer.class);
    }

    public CurrencyLayerRatesContainer getHistoricalRates(Calendar date) {
        return getEntity(URL_HISTORY + date.get(Calendar.YEAR) + "-" +
                        getStringWithLeftPadZero(date.get(Calendar.MONTH) + 1) + "-" +
                        getStringWithLeftPadZero(date.get(Calendar.DAY_OF_MONTH))
                , API_ID, CurrencyLayerRatesContainer.class);
    }

    private String getStringWithLeftPadZero(int number) {
// Path: src/main/java/com/github/vedenin/codingchallenge/exceptions/RestClientException.java
// public class RestClientException extends RuntimeException {
//     public RestClientException() {
//     }
// 
//     public RestClientException(String message) {
//         super(message);
//     }
// 
//     public RestClientException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public RestClientException(Throwable cause) {
//         super(cause);
//     }
// 
//     public RestClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/restclient/RestClient.java
// public interface RestClient {
//     BigDecimal getCurrentExchangeRates(CurrencyEnum currecnyFrom, CurrencyEnum currecnyTo);
//     BigDecimal getHistoricalExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, Calendar calendar);
// }
// 
// Path: src/main/java/com/github/vedenin/codingchallenge/common/CurrencyEnum.java
// public enum CurrencyEnum {
//     EUR("EUR", "Euro (EUR)"),
//     USD("USD", "US Dollar (USD)"),
//     GBP("GBP", "British Pound (GBP)"),
//     NZD("NZD", "New Zealand Dollar (NZD)"),
//     AUD("AUD", "Australian Dollar (AUD)"),
//     JPY("JPY", "Japanese Yen (JPY)"),
//     HUF("HUF", "Hungarian Forint (HUF)"),
//     RUB("RUB", "Russian Ruble (RUB)"),
//     PLN("PLN", "Polish Zloty (PLN)");
//     private final String code;
//     private final String description;
// 
//     CurrencyEnum(String code, String description) {
//         this.code = code;
//         this.description = description;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// }


// Path: src/main/java/com/github/vedenin/codingchallenge/restclient/impl/currencylayer/CurrencyLayerRestClient.java
import com.github.vedenin.codingchallenge.exceptions.RestClientException;
import com.github.vedenin.codingchallenge.restclient.RestClient;
import com.github.vedenin.codingchallenge.common.CurrencyEnum;
import org.springframework.stereotype.Service;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Response;
import java.math.BigDecimal;
import java.util.Calendar;
import static java.math.BigDecimal.ROUND_FLOOR;

package com.github.vedenin.codingchallenge.restclient.impl.currencylayer;




/**
 * Created by slava on 04.02.17.
 */
@Service("CurrencyLayer")
public class CurrencyLayerRestClient implements RestClient {
    private final static String URL_LAST = "http://www.apilayer.net/api/live?format=1";
    private final static String URL_HISTORY = "http://apilayer.net/api/historical?date=";
    private final static String API_ID = "f7e5948888d41713110273b47c682db0";
    private final static String API_ID_PRM = "&access_key=";
    private static final String ERROR_WHILE_GATHERING_INFORMATION = "Error while gathering information from CurrencyLayer services";


    public BigDecimal getCurrentExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo) {
        return getExchangeRates(currencyFrom, currencyTo, getCurrentRates());
    }

    public BigDecimal getHistoricalExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, Calendar calendar) {
        return getExchangeRates(currencyFrom, currencyTo, getHistoricalRates(calendar));
    }

    private BigDecimal getExchangeRates(CurrencyEnum currencyFrom, CurrencyEnum currencyTo, CurrencyLayerRatesContainer rates) {
        BigDecimal currencyFromRate = getRates(currencyFrom, rates);
        BigDecimal currencyToRate = getRates(currencyTo, rates);
        return currencyToRate.divide(currencyFromRate, 20, ROUND_FLOOR);
    }

    public CurrencyLayerRatesContainer getCurrentRates() {
        return getEntity(URL_LAST, API_ID, CurrencyLayerRatesContainer.class);
    }

    public CurrencyLayerRatesContainer getHistoricalRates(Calendar date) {
        return getEntity(URL_HISTORY + date.get(Calendar.YEAR) + "-" +
                        getStringWithLeftPadZero(date.get(Calendar.MONTH) + 1) + "-" +
                        getStringWithLeftPadZero(date.get(Calendar.DAY_OF_MONTH))
                , API_ID, CurrencyLayerRatesContainer.class);
    }

    private String getStringWithLeftPadZero(int number) {
        return String.format("%02d", number);