package org.knowm.xchange.huobi.service;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Collection;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.crypto.Mac;
import javax.ws.rs.FormParam;
import javax.ws.rs.QueryParam;
import org.knowm.xchange.service.BaseParamsDigest;
import si.mazi.rescu.Params;
import si.mazi.rescu.RestInvocation;

public class HuobiDigest extends BaseParamsDigest {

  private final Field invocationUrlField;
  private static final String PLACEHOLDER = "HUOBI_PLACEHOLDER";

  private HuobiDigest(String secretKey) {
    super(secretKey, HMAC_SHA_256);
    try {
      invocationUrlField = RestInvocation.class.getDeclaredField("invocationUrl");
      invocationUrlField.setAccessible(true);
    } catch (NoSuchFieldException e) {
      throw new IllegalStateException("rescu library has been updated");
    }
  }

  static HuobiDigest createInstance(String secretKey) {
    return secretKey == null ? null : new HuobiDigest(secretKey);
  }

  @Override
  public String digestParams(RestInvocation restInvocation) {
    String httpMethod = restInvocation.getHttpMethod();
    String host = getHost(restInvocation.getBaseUrl());
    String method = "/" + restInvocation.getMethodPath();
    String query =
        Stream.of(
                restInvocation.getParamsMap().get(FormParam.class),
                restInvocation.getParamsMap().get(QueryParam.class))
            .map(Params::asHttpHeaders)
            .map(Map::entrySet)
            .flatMap(Collection::stream)
            .filter(e -> !"Signature".equals(e.getKey()))
            .sorted(Map.Entry.comparingByKey())
            .map(e -> e.getKey() + "=" + encodeValue(e.getValue()))
            .collect(Collectors.joining("&"));
    String toSign = String.format("%s\n%s\n%s\n%s", httpMethod, host, method, query);
    Mac mac = getMac();
    String signature =
        encodeValue(Base64.getEncoder().encodeToString(mac.doFinal(toSign.getBytes())).trim());
    replaceSignatureUrl(restInvocation, signature);
    return signature;
  }

  private String getHost(String url) {
    URI uri;
    try {
      uri = new URI(url);
    } catch (URISyntaxException e) {
      throw new IllegalStateException(e.getMessage());
    }
    return uri.getHost();
  }

  private String encodeValue(String value) {
    String ret;
    try {
      ret = URLEncoder.encode(value, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      throw new IllegalStateException(e.getMessage());
    }
    return ret;
  }

  private void replaceSignatureUrl(RestInvocation restInvocation, String signature) {
    String invocationUrl = restInvocation.getInvocationUrl();
    String newInvocationUrl = invocationUrl.replace(PLACEHOLDER, signature);
    try {
      invocationUrlField.set(restInvocation, newInvocationUrl);
    } catch (IllegalAccessException e) {
      throw new IllegalStateException("rescu library has been updated");
    }
  }

  @Override
  public String toString() {
    return PLACEHOLDER;
  }
}

@@ -602,450 +602,86 @@
  %7B%0A%0A
-  private final Field invocationUrlField;%0A  private static final String PLACEHOLDER = %22HUOBI_PLACEHOLDER%22;%0A%0A  private HuobiDigest(String secretKey) %7B%0A    super(secretKey, HMAC_SHA_256);%0A    try %7B%0A      invocationUrlField = RestInvocation.class.getDeclaredField(%22invocationUrl%22);%0A      invocationUrlField.setAccessible(true);%0A    %7D catch (NoSuchFieldException e) %7B%0A      throw new IllegalStateException(%22rescu library has been updated%22);%0A    %7D
+%0A  private HuobiDigest(String secretKey) %7B%0A    super(secretKey, HMAC_SHA_256);
 %0A  %7D
@@ -1698,29 +1698,9 @@
 re =
-%0A        encodeValue(
+ 
 Base
@@ -1772,61 +1772,8 @@
 im()
-);%0A    replaceSignatureUrl(restInvocation, signature)
 ;%0A  
@@ -2265,499 +2265,6 @@
  %7D%0A%0A
-  private void replaceSignatureUrl(RestInvocation restInvocation, String signature) %7B%0A    String invocationUrl = restInvocation.getInvocationUrl();%0A    String newInvocationUrl = invocationUrl.replace(PLACEHOLDER, signature);%0A    try %7B%0A      invocationUrlField.set(restInvocation, newInvocationUrl);%0A    %7D catch (IllegalAccessException e) %7B%0A      throw new IllegalStateException(%22rescu library has been updated%22);%0A    %7D%0A  %7D%0A%0A  @Override%0A  public String toString() %7B%0A    return PLACEHOLDER;%0A  %7D%0A
 %7D%0A

remove huobi as well