package com.braintree.populators;

import com.braintree.command.result.BrainTreeBillingAddressResult;
import com.braintree.command.result.BrainTreePaymentDetailsResult;
import com.braintree.hybris.data.graphql.commands.response.BrainTreeAddress;
import com.braintree.hybris.data.graphql.commands.response.BraintreePaymentMethodData;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentMethodDetails;
import com.braintree.hybris.data.graphql.commands.response.BrainTreePaymentMethodOrigin;
import com.braintree.payment.info.service.BraintreePaymentInfoService;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.servicelayer.dto.converter.Converter;
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.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

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

    private static final String EXPIRATION_MONTH = "ExpirationMonth";
    private static final String EXPIRATION_YEAR = "ExpirationYear";
    private static final String CARD_HOLDER_NAME = "CardHolderName";
    private static final String LAST_FOUR = "1234";
    private static final String US_BANK_ACCOUNT_DETAIL = "UsBankAccountDetails";
    private static final String ORIGIN_TYPE = "OriginType";
    private static final String PAYMENT_PROVIDER = "PaymentProvider";
    private static final String BRAND_CODE = "Mastercard";
    private static final String IMAGE_URL = "ImageUrl";
    private static final String LEGACY_ID = "LegacyId";
    private static final String ID = "Id";
    private static final String EMAIL = "Email";
    private static final String ROUTING_NUMBER = "RoutingNumber";
    private static final String TYPE_NAME = "TypeName";
    private static final String CARD_NUMBER = "**************1234";

    @InjectMocks
    private BrainTreeGraphQLPaymentMethodToPaymentDetailsPopulator unit;

    @Mock
    private BraintreePaymentMethodData paymentMethod;
    @Mock
    private BrainTreePaymentMethodDetails paymentMethodDetails;
    @Mock
    private BrainTreePaymentMethodOrigin origin;
    @Mock
    private BraintreePaymentInfoService braintreePaymentInfoService;
    @Mock
    private Converter<BrainTreeAddress, BrainTreeBillingAddressResult> graphQLAddressToAddressResult;
    @Mock
    private BrainTreeAddress billingAddress;
    @Mock
    private BrainTreeBillingAddressResult billingAddressResult;

    @Test
    public void shouldPopulateBrainTreeGraphQLPaymentMethodToPaymentDetailsTest(){
        BrainTreePaymentDetailsResult target = new BrainTreePaymentDetailsResult();

        when(paymentMethod.getLegacyId()).thenReturn(LEGACY_ID);
        when(paymentMethod.getId()).thenReturn(ID);
        when(paymentMethod.getDetails()).thenReturn(paymentMethodDetails);
        when(paymentMethodDetails.getEmail()).thenReturn(EMAIL);
        when(paymentMethodDetails.getBrandCode()).thenReturn(BRAND_CODE);
        when(paymentMethodDetails.getExpirationMonth()).thenReturn(EXPIRATION_MONTH);
        when(paymentMethodDetails.getExpirationYear()).thenReturn(EXPIRATION_YEAR);
        when(paymentMethodDetails.getLast4()).thenReturn(LAST_FOUR);
        when(paymentMethodDetails.get__typename()).thenReturn(TYPE_NAME);
        when(paymentMethodDetails.getCardholderName()).thenReturn(CARD_HOLDER_NAME);
        when(paymentMethodDetails.getOrigin()).thenReturn(origin);
        when(origin.getType()).thenReturn(ORIGIN_TYPE);
        when(paymentMethodDetails.isVerified()).thenReturn(true);
        when(braintreePaymentInfoService.getPaymentProviderByDetailsAndOrigin(TYPE_NAME, ORIGIN_TYPE))
                .thenReturn(PAYMENT_PROVIDER);
        when(braintreePaymentInfoService.getImageSourceByPaymentProviderAndCardType(PAYMENT_PROVIDER, BRAND_CODE))
                .thenReturn(IMAGE_URL);
        when(paymentMethodDetails.getBillingAddress()).thenReturn(billingAddress);
        when(graphQLAddressToAddressResult.convert(billingAddress)).thenReturn(billingAddressResult);

        unit.populate(paymentMethod, target);

        assertEquals(LEGACY_ID, target.getPaymentMethodToken());
        assertEquals(ID, target.getPaymentMethodGraphQLToken());
        assertEquals(EMAIL, target.getEmail());
        assertEquals(BRAND_CODE, target.getCardType());
        assertEquals(EXPIRATION_MONTH, target.getExpirationMonth());
        assertEquals(EXPIRATION_YEAR, target.getExpirationYear());
        assertEquals(LAST_FOUR, target.getLast4());
        assertEquals(CARD_NUMBER, target.getCardNumber());
        assertEquals(CARD_HOLDER_NAME, target.getCardholderName());
        assertNull(target.getRoutingNumber());
        assertTrue(target.getVerified());
        assertEquals(PAYMENT_PROVIDER, target.getPaymentProvider());
        assertEquals(IMAGE_URL, target.getImageUrl());
        assertEquals(billingAddressResult, target.getBillingAddress());

    }

    @Test
    public void shouldPopulateBrainTreeGrddaphQLPaymentMethodToACHPaymentDetailsTest(){
        BrainTreePaymentDetailsResult target = new BrainTreePaymentDetailsResult();

        when(paymentMethod.getLegacyId()).thenReturn(LEGACY_ID);
        when(paymentMethod.getId()).thenReturn(ID);
        when(paymentMethod.getDetails()).thenReturn(paymentMethodDetails);
        when(paymentMethodDetails.getEmail()).thenReturn(EMAIL);
        when(paymentMethodDetails.getBrandCode()).thenReturn(BRAND_CODE);
        when(paymentMethodDetails.get__typename()).thenReturn(US_BANK_ACCOUNT_DETAIL);
        when(paymentMethodDetails.getOrigin()).thenReturn(origin);
        when(origin.getType()).thenReturn(ORIGIN_TYPE);
        when(paymentMethodDetails.getRoutingNumber()).thenReturn(ROUTING_NUMBER);
        when(paymentMethodDetails.isVerified()).thenReturn(true);
        when(braintreePaymentInfoService.getPaymentProviderByDetailsAndOrigin(US_BANK_ACCOUNT_DETAIL, ORIGIN_TYPE))
                .thenReturn(PAYMENT_PROVIDER);
        when(braintreePaymentInfoService.getImageSourceByPaymentProviderAndCardType(PAYMENT_PROVIDER, BRAND_CODE))
                .thenReturn(IMAGE_URL);
        when(paymentMethodDetails.getBillingAddress()).thenReturn(billingAddress);
        when(graphQLAddressToAddressResult.convert(billingAddress)).thenReturn(billingAddressResult);

        unit.populate(paymentMethod, target);

        assertEquals(LEGACY_ID, target.getPaymentMethodToken());
        assertEquals(ID, target.getPaymentMethodGraphQLToken());
        assertEquals(EMAIL, target.getEmail());
        assertEquals(BRAND_CODE, target.getCardType());
        assertEquals(StringUtils.EMPTY, target.getExpirationMonth());
        assertEquals(StringUtils.EMPTY, target.getExpirationYear());
        assertEquals(StringUtils.EMPTY, target.getCardNumber());
        assertEquals(StringUtils.EMPTY, target.getCardholderName());
        assertEquals(ROUTING_NUMBER, target.getRoutingNumber());
        assertTrue(target.getVerified());
        assertEquals(PAYMENT_PROVIDER, target.getPaymentProvider());
        assertEquals(IMAGE_URL, target.getImageUrl());
        assertEquals(billingAddressResult,target.getBillingAddress());
    }
}
