package ee.bitweb.banklinksdk.protocol.iPizza;

import ee.bitweb.banklinksdk.protocol.FieldDefinition;
import ee.bitweb.banklinksdk.protocol.Protocol;
import ee.bitweb.banklinksdk.protocol.Vendor;
import ee.bitweb.banklinksdk.request.PaymentRequestParams;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

/**
 * Created by tobre on 18/03/2017.
 */
public class iPizzaProtocol extends Protocol {

    protected String publicKey;
    protected String privateKey;

    protected Vendor vendor;


    public iPizzaProtocol(String publicKey, String privateKey, Vendor vendor) {
        //TODO: Check parameters and throw IllegalArgumentException

        this.publicKey = publicKey;
        this.privateKey = privateKey;
        this.vendor = vendor;
    }

    public Map<FieldDefinition, String> preparePaymentRequest(PaymentRequestParams paymentRequestParams) {
        Map<FieldDefinition, String> requestData = new HashMap<>();
        requestData.put(Fields.SERVICE, Services.PAYMENT_REQUEST.code);
        requestData.put(Fields.VERSION, version);

        requestData.put(Fields.SND_ID, vendor.getSenderId());
        requestData.put(Fields.STAMP, ""); //FIXME siia mingi jama
        requestData.put(Fields.AMOUNT, String.valueOf(paymentRequestParams.getAmount()));
        requestData.put(Fields.CURR, paymentRequestParams.getCurrency());
        requestData.put(Fields.REF, paymentRequestParams.getReferenceNumber());
        requestData.put(Fields.MSG, paymentRequestParams.getMessage());
        requestData.put(Fields.RETURN_URL, paymentRequestParams.getSuccessUri());
        requestData.put(Fields.CANCEL_URL, paymentRequestParams.getCancelUri());
        requestData.put(Fields.DATETIME, formatDate(new Date()));

        requestData.put(Fields.ENCODING, paymentRequestParams.getEncoding());
        requestData.put(Fields.LANG, paymentRequestParams.getLanguage());

        requestData.put(Fields.MAC, getRequestSignature(getMac(requestData, Services.PAYMENT_REQUEST)));

        return requestData;

    }


    protected String getRequestSignature(String mac) {

        //TODO: signing with private key


        return mac;
    }

    protected String getMac(Map<FieldDefinition, String> requestData, Services service) {
        String data = "";

        for (FieldDefinition field : Services.getFields(service)) {
            data += padMacParameter(field.getLength(), requestData.get(field));
        }

        return data;
    }


    private String formatDate(Date date) {
        TimeZone tz = TimeZone.getTimeZone("UTC");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
        formatter.setTimeZone(tz);

        return formatter.format(date);
    }

    private String padMacParameter(int length, String value) {
        String prefix = "";
        int prefixLen = length - value.length();

        for (int i = 0; i < prefixLen; i++) {
            prefix += "0";
        }

        return prefix + value;
    }
}

@@ -41,16 +41,74 @@
 Pizza;%0A%0A
+import ee.bitweb.banklinksdk.exception.BanklinkException;%0A
 import e
@@ -308,16 +308,248 @@
 arams;%0A%0A
+import java.nio.ByteBuffer;%0Aimport java.security.*;%0Aimport java.security.interfaces.RSAPrivateKey;%0Aimport java.security.spec.InvalidKeySpecException;%0Aimport java.security.spec.KeySpec;%0Aimport java.security.spec.PKCS8EncodedKeySpec;%0A
 import j
@@ -2244,24 +2244,42 @@
 nguage());%0A%0A
+        try %7B%0A    
         requ
@@ -2375,163 +2375,985 @@
 ));%0A
-%0A        return requestData;%0A%0A    %7D%0A%0A%0A    protected String getRequestSignature(String mac) %7B%0A%0A        //TODO: signing with private key%0A%0A%0A        return mac
+        %7D catch (NoSuchAlgorithmException %7C InvalidKeyException %7C SignatureException %7C InvalidKeySpecException e) %7B%0A            throw new BanklinkException(e);%0A        %7D%0A%0A        return requestData;%0A%0A    %7D%0A%0A    //FIXME: Encapuslate to Helper%0A    private RSAPrivateKey loadPrivateRSAKeyFromFile() throws NoSuchAlgorithmException, InvalidKeySpecException %7B%0A        KeyFactory kFact = KeyFactory.getInstance(%22RSA%22);%0A        KeySpec ks = new PKCS8EncodedKeySpec(privateKey.getBytes());%0A%0A        return (RSAPrivateKey)kFact.generatePrivate(ks);%0A    %7D%0A%0A    protected String getRequestSignature(String mac) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, InvalidKeySpecException %7B%0A        RSAPrivateKey privKey = loadPrivateRSAKeyFromFile();%0A        Signature s = Signature.getInstance(%22SHA256withRSA%22);%0A        s.initSign(privKey);%0A        s.update(ByteBuffer.wrap(mac.getBytes()));%0A        byte%5B%5D signature = s.sign();%0A%0A        return new String(signature)
 ;%0A  

Add mac signign