package com.braintree.service.impl;

import static com.braintree.constants.BraintreeConstants.BRAINTREE_PROVIDER_NAME;

import com.braintree.commands.impl.DefaultBrainTreeGetPayPalAccessTokenCommand;
import com.braintree.commands.impl.DefaultBrainTreeConnectWithPayPalExchangeCodeToAccessTokenCommand;
import com.braintree.commands.impl.DefaultBrainTreeConnectWithPayPalGetUserInformationCommand;
import com.braintree.exceptions.BrainTreeConnectWithPayPalException;
import com.braintree.hybris.data.BrainTreeConnectWithPayPalUserData;
import com.braintree.service.BrainTreeConnectWithPayPalService;
import de.hybris.platform.payment.AdapterException;
import de.hybris.platform.payment.commands.factory.CommandFactory;
import de.hybris.platform.payment.commands.factory.CommandFactoryRegistry;
import de.hybris.platform.payment.commands.factory.CommandNotSupportedException;
import de.hybris.platform.payment.commands.factory.impl.DefaultCommandFactoryRegistryImpl;
import org.apache.log4j.Logger;

public class DefaultBrainTreeConnectWithPayPalService implements BrainTreeConnectWithPayPalService {

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

    private CommandFactoryRegistry commandFactoryRegistry;

    @Override
    public String getAccessToken() {
        try {
            DefaultBrainTreeGetPayPalAccessTokenCommand command = getCommandFactory()
                    .createCommand(DefaultBrainTreeGetPayPalAccessTokenCommand.class);
            return command.perform(null).getAccessToken();
        } catch (CommandNotSupportedException | AdapterException e) {
            LOG.error(String.format("Exception, message : %s", e.getMessage()), e);
            throw new BrainTreeConnectWithPayPalException(e);
        }
    }

    @Override
    public String exchangeAuthorizationCodeToAccessToken(String authorizationToken) {
        try {
            DefaultBrainTreeConnectWithPayPalExchangeCodeToAccessTokenCommand command = getCommandFactory()
                    .createCommand(DefaultBrainTreeConnectWithPayPalExchangeCodeToAccessTokenCommand.class);
            return command.perform(authorizationToken).getAccessToken();
        } catch (CommandNotSupportedException | AdapterException e) {
            LOG.error(String.format("Exception, message : %s", e.getMessage()), e);
            throw new BrainTreeConnectWithPayPalException(e);
        }
    }

    @Override
    public BrainTreeConnectWithPayPalUserData getUserDataByAccessToken(String accessToken) {
        try {
            DefaultBrainTreeConnectWithPayPalGetUserInformationCommand command = getCommandFactory()
                .createCommand(DefaultBrainTreeConnectWithPayPalGetUserInformationCommand.class);
            return command.perform(accessToken);
        } catch (CommandNotSupportedException e) {
            LOG.error(String.format("Exception, message : %s", e.getMessage()), e);
            throw new AdapterException(e);
        }
    }

    public void setCommandFactoryRegistry(DefaultCommandFactoryRegistryImpl commandFactoryRegistry) {
        this.commandFactoryRegistry = commandFactoryRegistry;
    }

    private CommandFactory getCommandFactory() {
        return commandFactoryRegistry.getFactory(BRAINTREE_PROVIDER_NAME);
    }
}
