/*
 *                       ######
 *                       ######
 * ############    ####( ######  #####. ######  ############   ############
 * #############  #####( ######  #####. ######  #############  #############
 *        ######  #####( ######  #####. ######  #####  ######  #####  ######
 * ###### ######  #####( ######  #####. ######  #####  #####   #####  ######
 * ###### ######  #####( ######  #####. ######  #####          #####  ######
 * #############  #############  #############  #############  #####  ######
 *  ############   ############  #############   ############  #####  ######
 *                                      ######
 *                               #############
 *                               ############
 *
 * Adyen Hybris Extension
 *
 * Copyright (c) 2019 Adyen B.V.
 * This file is open source and available under the MIT license.
 * See the LICENSE file for more info.
 */
package com.adyen.v6.converters;

import com.adyen.model.checkout.PaymentsResponse;
import com.adyen.model.nexo.SaleToPOIResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.springframework.core.convert.converter.Converter;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PosPaymentResponseConverter implements Converter<SaleToPOIResponse, PaymentsResponse> {
    @Override
    public PaymentsResponse convert(SaleToPOIResponse saleToPOIResponse) {
        String pspReference = null;
        Map<String, String> additionalData = null;
        String additionalResponse = null;

        if (saleToPOIResponse != null && saleToPOIResponse.getPaymentResponse() != null) {
            pspReference = saleToPOIResponse.getPaymentResponse()
                                            .getPaymentResult()
                                            .getPaymentAcquirerData()
                                            .getAcquirerTransactionID()
                                            .getTransactionID();

            additionalResponse = saleToPOIResponse.getPaymentResponse()
                                                  .getResponse()
                                                  .getAdditionalResponse();

        } else if (saleToPOIResponse != null && saleToPOIResponse.getTransactionStatusResponse() != null) {
            pspReference = saleToPOIResponse.getTransactionStatusResponse()
                                            .getRepeatedMessageResponse()
                                            .getRepeatedResponseMessageBody()
                                            .getPaymentResponse()
                                            .getPaymentResult()
                                            .getPaymentAcquirerData()
                                            .getAcquirerTransactionID()
                                            .getTransactionID();

            additionalResponse = saleToPOIResponse.getTransactionStatusResponse()
                                                  .getRepeatedMessageResponse()
                                                  .getRepeatedResponseMessageBody()
                                                  .getPaymentResponse()
                                                  .getResponse()
                                                  .getAdditionalResponse();
        }
        if (additionalResponse != null) {
            additionalData = parseAdditionalResponse(additionalResponse);
        }
        PaymentsResponse paymentsResponse = new PaymentsResponse();
        paymentsResponse.setPspReference(pspReference);
        paymentsResponse.setAdditionalData(additionalData);

        return paymentsResponse;
    }

    /*
     * Parse additionalResponse with a query string format, i.e. "tid=123&AID=123&transactionType=GOODS_SERVICES&..."),
     * and return as a name/value map
     */
    private Map<String, String> parseAdditionalResponse(String additionalResponse) {
        Map<String, String> additionalData = new HashMap<>();
        if (StringUtils.isNotEmpty(additionalResponse)) {
            List<NameValuePair> parsedNameValues = URLEncodedUtils.parse(additionalResponse, Charset.forName("UTF-8"));
            for (NameValuePair nameValue : parsedNameValues) {
                additionalData.put(nameValue.getName(), nameValue.getValue());
            }
        }
        return additionalData;
    }
}

@@ -1041,32 +1041,61 @@
 esponse;%0Aimport 
+com.google.gson.Gson;%0Aimport 
 org.apache.commo
@@ -1113,99 +1113,8 @@
 ring
-Utils;%0Aimport org.apache.http.NameValuePair;%0Aimport org.apache.http.client.utils.URLEncoded
 Util
@@ -1202,23 +1202,32 @@
 charset.
+Standard
 Charset
+s
 ;%0Aimport
@@ -1237,23 +1237,22 @@
 va.util.
-HashMap
+Base64
 ;%0Aimport
@@ -1262,20 +1262,23 @@
 va.util.
-List
+HashMap
 ;%0Aimport
@@ -3771,16 +3771,31 @@
 * Parse 
+base64 encoded 
 addition
@@ -3808,103 +3808,8 @@
 onse
- with a query string format, i.e. %22tid=123&AID=123&transactionType=GOODS_SERVICES&...%22),%0A     *
  and
@@ -4065,67 +4065,79 @@
     
-List%3CNameValuePair%3E parsedNameValues = URLEncodedUtils.pars
+String decodedAdditionalResponse = new String(Base64.getDecoder().decod
 e(ad
@@ -4156,192 +4156,186 @@
 onse
+)
 , 
-Charset.forName(%22UTF-8%22));%0A            for (NameValuePair nameValue : parsedNameValues) %7B%0A                additionalData.put(nameValue.getName(), nameValue.getValue());%0A            %7D
+StandardCharsets.UTF_8);%0A            Gson gson = new Gson();%0A            additionalData = gson.fromJson(decodedAdditionalResponse, PaymentsResponse.class).getAdditionalData();
 %0A   

Fix additionalResponse parsing on Terminal API Response (#197)