package com.xeiam.xchange.mtgox.v2.service.account.polling;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import si.mazi.rescu.ParamsDigest;
import si.mazi.rescu.RestInvocationParams;

/**
 * @author Matija Mazi <br/>
 * @created 5/12/13 9:33 PM
 *
 * TODO! this doesn't work yet.
 */
public class MtGoxV2Digest implements ParamsDigest {

  private static final Logger log = LoggerFactory.getLogger(MtGoxV2Digest.class);

  private static final String HMAC_SHA_512 = "HmacSHA512";
  private final Mac mac;

  /**
   * Constructor
   *
   * @param secretKeyBase64
   * @throws IllegalArgumentException if key is invalid (cannot be base-64-decoded or the decoded key is invalid).
   */
  private MtGoxV2Digest(String secretKeyBase64) throws IllegalArgumentException {

    try {
      SecretKey secretKey = new SecretKeySpec(secretKeyBase64.getBytes("UTF-8"), HMAC_SHA_512);
      mac = Mac.getInstance(HMAC_SHA_512);
      mac.init(secretKey);
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("Illegal encoding, check the code.", e);
    } catch (InvalidKeyException e) {
      throw new IllegalArgumentException("Invalid key for hmac initialization.", e);
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException("Illegal algorithm for post body digest. Check the implementation.");
    }
  }

  public static MtGoxV2Digest createInstance(String secretKeyBase64) throws IllegalArgumentException {

    return secretKeyBase64 == null ? null : new MtGoxV2Digest(secretKeyBase64);
  }

  @Override
  public String digestParams(RestInvocationParams restInvocationParams) {

    try {
      String postBody = restInvocationParams.getRequestBody();
      String methodPath = restInvocationParams.getMethodPath();
      log.debug("methodPath = {}", methodPath);
      mac.update(methodPath.getBytes("UTF-8"));
      mac.update((byte) 0);
      mac.update(postBody.getBytes("UTF-8"));
      return String.format("%0128x", new BigInteger(1, mac.doFinal()));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException("Illegal encoding, check the code.", e);
    }
    // return Base64.encodeBytes(mac.doFinal()).trim();
  }
}

@@ -1,137 +1,1230 @@
-package com.xeiam.xchange.mtgox.v2.service.account.polling;%0A%0Aimport java.io.UnsupportedEncodingException;%0Aimport java.math.BigInteger
+/**%0A * Copyright (C) 2012 - 2013 Xeiam LLC http://xeiam.com%0A *%0A * Permission is hereby granted, free of charge, to any person obtaining a copy of%0A * this software and associated documentation files (the %22Software%22), to deal in%0A * the Software without restriction, including without limitation the rights to%0A * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies%0A * of the Software, and to permit persons to whom the Software is furnished to do%0A * so, subject to the following conditions:%0A *%0A * The above copyright notice and this permission notice shall be included in all%0A * copies or substantial portions of the Software.%0A *%0A * THE SOFTWARE IS PROVIDED %22AS IS%22, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR%0A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,%0A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE%0A * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER%0A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,%0A * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE%0A * SOFTWARE.%0A */%0Apackage com.xeiam.xchange.mtgox.v2.service.account.polling;%0A%0Aimport java.io.IOException
 ;%0Aim
@@ -1412,66 +1412,8 @@
 c;%0A%0A
-import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 impo
@@ -1485,16 +1485,51 @@
 nParams;
+%0Aimport si.mazi.rescu.utils.Base64;
 %0A%0A/**%0A *
@@ -1680,91 +1680,8 @@
  %7B%0A%0A
-  private static final Logger log = LoggerFactory.getLogger(MtGoxV2Digest.class);%0A%0A
   pr
@@ -2077,16 +2077,30 @@
 KeySpec(
+Base64.decode(
 secretKe
@@ -2116,23 +2116,17 @@
 etBytes(
-%22UTF-8%22
+)
 ), HMAC_
@@ -2218,35 +2218,18 @@
  catch (
-UnsupportedEncoding
+IO
 Exceptio
@@ -2255,59 +2255,65 @@
 new 
-RuntimeException(%22Illegal encoding, check the code.
+IllegalArgumentException(%22Could not decode Base 64 string
 %22, e
@@ -2788,20 +2788,8 @@
  %7D%0A%0A
-  @Override%0A
   pu
@@ -2867,216 +2867,55 @@
     
-try %7B%0A      String postBody = restInvocationParams.getRequestBody();%0A      String methodPath = restInvocationParams.getMethodPath();%0A      log.debug(%22methodPath = %7B%7D%22, methodPath);%0A      mac.update(methodPath
+mac.update(restInvocationParams.getMethodPath()
 .get
@@ -2916,37 +2916,28 @@
 ().getBytes(
-%22UTF-8%22
 ));%0A
-  
     mac.upda
@@ -2943,21 +2943,24 @@
 ate(
-(byte) 0
+new byte%5B%5D%7B0%7D
 );%0A
-  
     
@@ -2974,242 +2974,62 @@
 ate(
-postBody.getBytes(%22UTF-8%22));%0A      return String.format(%22%250128x%22, new BigInteger(1, mac.doFinal()));%0A    %7D catch (UnsupportedEncodingException e) %7B%0A      throw new RuntimeException(%22Illegal encoding, check the code.%22, e);%0A    %7D%0A    //
+restInvocationParams.getRequestBody().getBytes());%0A   
  ret
@@ -3079,9 +3079,8 @@
 );%0A  %7D%0A%7D
-%0A

Fix this (Use Base64; this was originally copied from the wrong implementation, hence the error). Still doesn't work, unfortunately.