package com.braintree.populators;

import com.braintree.command.result.BrainTreePaymentDetailsResult;
import com.braintree.enums.BrainTreePaymentMethod;
import com.braintreegateway.AndroidPayCard;
import com.braintreegateway.CreditCard;
import com.braintreegateway.PayPalAccount;
import com.braintreegateway.VenmoAccount;
import com.braintreegateway.VisaCheckoutCard;
import de.hybris.bootstrap.annotations.UnitTest;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

@UnitTest
@RunWith(MockitoJUnitRunner.class)
public class BrainTreePaymentMethodToPaymentDetailsPopulatorTest {

    private static final String PAY_PAL_TOKEN = "PayPalToken";
    private static final String PAY_PAL_IMAGE_URL = "PayPalImageURL";
    private static final String PAY_PAL_EMAIL = "PayPalEmail";
    private static final String CREDIT_CARD_TOKEN = "CreditCardToken";
    private static final String CARD_TYPE = "CardType";
    private static final String EXPIRATION_MONTH = "ExpirationMonth";
    private static final String EXPIRATION_YEAR = "ExpirationYear";
    private static final String MASKED_NUMBER = "MaskedNumber";
    private static final String CARD_HOLDER_NAME = "CardHolderName";
    private static final String CREDIT_CARD_IMAGE_URL = "CreditCardImageURL";
    private static final String VENMO_TOKEN = "VenmoToken";
    private static final String VENMO_IMAGE_URL = "VenmoImageURL";
    private static final String ANDROID_CARD_PAY_TOKEN = "AndroidCardPayToken";
    private static final String ANDROID_CARD_PAY_IMAGE_URL = "AndroidCardPayImageUrl";
    private static final String SOURS_ANDROID_CARD_TYPE = "SoursAndroidCardType";
    private static final String LAST_FOUR = "1234";
    private static final String MASKED_CARD_NUMBER = "**************1234";
    private static final String SRC_TOKEN = "SRCToken";
    private static final String SRC_IMAGE_URL = "SRCImageURL";
    private static final String SRC_CARD_TYPE = "SRCCardType";

    @InjectMocks
    private BrainTreePaymentMethodToPaymentDetailsPopulator unit;

    @Mock
    private PayPalAccount payPalAccount;
    @Mock
    private CreditCard creditCard;
    @Mock
    private VenmoAccount venmoAccount;
    @Mock
    private AndroidPayCard androidPayCard;
    @Mock
    private VisaCheckoutCard visaCheckoutCard;

    @Test
    public void shouldPopulatePayPalAccountToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();

        when(payPalAccount.getToken()).thenReturn(PAY_PAL_TOKEN);
        when(payPalAccount.getImageUrl()).thenReturn(PAY_PAL_IMAGE_URL);
        when(payPalAccount.getEmail()).thenReturn(PAY_PAL_EMAIL);

        unit.populate(payPalAccount, brainTreePaymentDetailsResult);

        assertEquals(BrainTreePaymentMethod.PAYPALACCOUNT.getCode(), brainTreePaymentDetailsResult.getPaymentProvider());
        assertEquals(PAY_PAL_TOKEN, brainTreePaymentDetailsResult.getPaymentMethodToken());
        assertEquals(PAY_PAL_IMAGE_URL, brainTreePaymentDetailsResult.getImageUrl());
        assertEquals(PAY_PAL_EMAIL, brainTreePaymentDetailsResult.getEmail());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getExpirationMonth());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardType());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getExpirationYear());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardNumber());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardholderName());

    }

    @Test
    public void shouldPopulateCreditCardToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();

        when(creditCard.getToken()).thenReturn(CREDIT_CARD_TOKEN);
        when(creditCard.getCardType()).thenReturn(CARD_TYPE);
        when(creditCard.getExpirationMonth()).thenReturn(EXPIRATION_MONTH);
        when(creditCard.getExpirationYear()).thenReturn(EXPIRATION_YEAR);
        when(creditCard.getMaskedNumber()).thenReturn(MASKED_NUMBER);
        when(creditCard.getCardholderName()).thenReturn(CARD_HOLDER_NAME);
        when(creditCard.getImageUrl()).thenReturn(CREDIT_CARD_IMAGE_URL);

        unit.populate(creditCard, brainTreePaymentDetailsResult);

        assertEquals(BrainTreePaymentMethod.CREDITCARD.getCode(), brainTreePaymentDetailsResult.getPaymentProvider());
        assertEquals(CREDIT_CARD_TOKEN, brainTreePaymentDetailsResult.getPaymentMethodToken());
        assertEquals(EXPIRATION_MONTH, brainTreePaymentDetailsResult.getExpirationMonth());
        assertEquals(EXPIRATION_YEAR, brainTreePaymentDetailsResult.getExpirationYear());
        assertEquals(MASKED_NUMBER, brainTreePaymentDetailsResult.getCardNumber());
        assertEquals(CARD_HOLDER_NAME, brainTreePaymentDetailsResult.getCardholderName());
        assertEquals(CREDIT_CARD_IMAGE_URL, brainTreePaymentDetailsResult.getImageUrl());
    }

    @Test
    public void shouldPopulateVenmoToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();

        when(venmoAccount.getToken()).thenReturn(VENMO_TOKEN);
        when(venmoAccount.getImageUrl()).thenReturn(VENMO_IMAGE_URL);

        unit.populate(venmoAccount, brainTreePaymentDetailsResult);

        assertEquals(BrainTreePaymentMethod.VENMOACCOUNT.getCode(), brainTreePaymentDetailsResult.getPaymentProvider());
        assertEquals(VENMO_TOKEN, brainTreePaymentDetailsResult.getPaymentMethodToken());
        assertEquals(VENMO_IMAGE_URL, brainTreePaymentDetailsResult.getImageUrl());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getExpirationMonth());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardType());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getExpirationYear());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardNumber());
        assertEquals(StringUtils.EMPTY, brainTreePaymentDetailsResult.getCardholderName());
    }

    @Test
    public void shouldPopulateAndroidPayCardToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();

        when(androidPayCard.getToken()).thenReturn(ANDROID_CARD_PAY_TOKEN);
        when(androidPayCard.getImageUrl()).thenReturn(ANDROID_CARD_PAY_IMAGE_URL);
        when(androidPayCard.getSourceCardType()).thenReturn(SOURS_ANDROID_CARD_TYPE);
        when(androidPayCard.getExpirationMonth()).thenReturn(EXPIRATION_MONTH);
        when(androidPayCard.getExpirationYear()).thenReturn(EXPIRATION_YEAR);
        when(androidPayCard.getSourceCardLast4()).thenReturn(LAST_FOUR);

        unit.populate(androidPayCard, brainTreePaymentDetailsResult);

        assertEquals(BrainTreePaymentMethod.ANDROIDPAYCARD.getCode(), brainTreePaymentDetailsResult.getPaymentProvider());
        assertEquals(ANDROID_CARD_PAY_TOKEN, brainTreePaymentDetailsResult.getPaymentMethodToken());
        assertEquals(SOURS_ANDROID_CARD_TYPE, brainTreePaymentDetailsResult.getCardType());
        assertEquals(EXPIRATION_MONTH, brainTreePaymentDetailsResult.getExpirationMonth());
        assertEquals(EXPIRATION_YEAR, brainTreePaymentDetailsResult.getExpirationYear());
        assertEquals(MASKED_CARD_NUMBER, brainTreePaymentDetailsResult.getCardNumber());
        assertEquals(ANDROID_CARD_PAY_IMAGE_URL, brainTreePaymentDetailsResult.getImageUrl());
    }

    @Test
    public void shouldPopulateSRCToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult brainTreePaymentDetailsResult = new BrainTreePaymentDetailsResult();

        when(visaCheckoutCard.getToken()).thenReturn(SRC_TOKEN);
        when(visaCheckoutCard.getImageUrl()).thenReturn(SRC_IMAGE_URL);
        when(visaCheckoutCard.getCardType()).thenReturn(SRC_CARD_TYPE);
        when(visaCheckoutCard.getExpirationMonth()).thenReturn(EXPIRATION_MONTH);
        when(visaCheckoutCard.getExpirationYear()).thenReturn(EXPIRATION_YEAR);
        when(visaCheckoutCard.getLast4()).thenReturn(LAST_FOUR);

        unit.populate(visaCheckoutCard, brainTreePaymentDetailsResult);

        assertEquals(BrainTreePaymentMethod.VISACHECKOUTCARD.getCode(), brainTreePaymentDetailsResult.getPaymentProvider());
        assertEquals(SRC_TOKEN, brainTreePaymentDetailsResult.getPaymentMethodToken());
        assertEquals(SRC_IMAGE_URL, brainTreePaymentDetailsResult.getImageUrl());
        assertEquals(SRC_CARD_TYPE, brainTreePaymentDetailsResult.getCardType());
        assertEquals(EXPIRATION_MONTH, brainTreePaymentDetailsResult.getExpirationMonth());
        assertEquals(EXPIRATION_YEAR, brainTreePaymentDetailsResult.getExpirationYear());
        assertEquals(MASKED_CARD_NUMBER, brainTreePaymentDetailsResult.getCardNumber());
    }
}