package com.braintree.commands.impl;

import com.braintree.hybris.data.BrainTreeConnectWithPayPalAccessTokenData;
import de.hybris.platform.payment.AdapterException;
import de.hybris.platform.payment.commands.Command;
import org.apache.log4j.Logger;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Base64;

public class DefaultBrainTreeConnectWithPayPalExchangeCodeToAccessTokenCommand
        extends AbstractCommand implements Command<String, BrainTreeConnectWithPayPalAccessTokenData> {

    private static final Logger LOG = Logger.getLogger(DefaultBrainTreeConnectWithPayPalExchangeCodeToAccessTokenCommand.class);

    private static final String EXCHANGE_ENDPOINT_URL = "oauth2/token";
    private static final String GRANT_TYPE = "grant_type";
    private static final String GRANT_TYPE_VALUE = "authorization_code";
    private static final String CODE = "code";
    private static final String ERROR_MESSAGE = "Error during try exchange authorization token to access token";

    private RestTemplate restTemplate;

    @Override
    public BrainTreeConnectWithPayPalAccessTokenData perform(String authorizationCode) {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add(GRANT_TYPE,GRANT_TYPE_VALUE);
        map.add(CODE,authorizationCode);
        HttpHeaders headers = new HttpHeaders();
        String endpointUrl = getBrainTreeConfigService().getPayPalApiUrl().concat(EXCHANGE_ENDPOINT_URL);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setBasicAuth(getAuthorizationHeaderValue());
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, headers);
        ResponseEntity<BrainTreeConnectWithPayPalAccessTokenData> response;
        try {
            response = restTemplate
                    .postForEntity(endpointUrl, httpEntity, BrainTreeConnectWithPayPalAccessTokenData.class);
        } catch (Exception e) {
            LOG.error(ERROR_MESSAGE, e);
            throw new AdapterException(e.getMessage());
        }
        return response.getBody();
    }

    private String getAuthorizationHeaderValue() {
        String clientIdAndSecret = getBrainTreeConfigService().getClientID() + ":"
                + getBrainTreeConfigService().getSecretKey();
        return new String(Base64.getEncoder().encode(clientIdAndSecret.getBytes()));
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
}
