package com.braintree.commands.impl;

import com.braintree.hybris.data.BrainTreeGetPayPalAccessTokenData;
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 DefaultBrainTreeGetPayPalAccessTokenCommand
        extends AbstractCommand implements Command<Object, BrainTreeGetPayPalAccessTokenData> {

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

    private static final String ENDPOINT_URL = "https://api-m.sandbox.paypal.com/v1/oauth2/token";
    private static final String GRANT_TYPE = "grant_type";
    private static final String GRANT_TYPE_VALUE = "client_credentials";
    private static final String ERROR_MESSAGE = "Error during try to get a access token";

    private RestTemplate restTemplate;

    @Override
    public BrainTreeGetPayPalAccessTokenData perform(Object o) {
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add(GRANT_TYPE, GRANT_TYPE_VALUE);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setBasicAuth(getAuthorizationHeaderValue());
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, headers);
        ResponseEntity<BrainTreeGetPayPalAccessTokenData> response;
        try {
            response = restTemplate
                    .postForEntity(ENDPOINT_URL, httpEntity, BrainTreeGetPayPalAccessTokenData.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;
    }
}