package com.braintreeocc.converters.populators;

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

import com.braintree.hybris.data.ws.ApplePayAddressWsDTO;
import com.braintree.paypal.validator.BraintreePayPalAddressDetailValidator;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.commercefacades.user.data.AddressData;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

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

    private static final String COUNTY_CODE = "countyCode";
    private static final String ADMINISTRATIVE_AREA = "countyCode";
    private static final String LINE_1 = "line1";
    private static final String LINE_2 = "line2";
    private static final String POSTAL_CODE = "postalCOde";
    private static final String LOCALITY = "Locality";
    private static final String FIRST_NAME = "firstName";
    private static final String LAST_NAME = "lastName";

    @Mock
    private BraintreePayPalAddressDetailValidator payPalAddressDetailValidator;
    @Mock
    private ApplePayAddressWsDTO applePayAddress;

    @InjectMocks
    private BraintreeApplePayAddressPopulator unit;


    @Before
    public void setUp() {
        applePayAddress = Mockito.mock(ApplePayAddressWsDTO.class);
        when(applePayAddress.getCountryCode()).thenReturn(COUNTY_CODE);
        when(applePayAddress.getAdministrativeArea()).thenReturn(ADMINISTRATIVE_AREA);
        when(applePayAddress.getPostalCode()).thenReturn(POSTAL_CODE);
        when(applePayAddress.getLocality()).thenReturn(LOCALITY);
        when(applePayAddress.getGivenName()).thenReturn(FIRST_NAME);
        when(applePayAddress.getFamilyName()).thenReturn(LAST_NAME);
    }

    @Test
    public void populateShouldSetRequiredFields() {
        AddressData addressData = new AddressData();

        when(payPalAddressDetailValidator.validatePayPalCountryCode(COUNTY_CODE)).thenReturn(true);
        when(payPalAddressDetailValidator.validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA)).thenReturn(true);
        List<String> addressLines = new ArrayList<>();
        addressLines.add(LINE_1);
        addressLines.add(LINE_2);
        when(applePayAddress.getAddressLines()).thenReturn(addressLines);

        unit.populate(applePayAddress, addressData);
        verify(payPalAddressDetailValidator).validatePayPalCountryCode(COUNTY_CODE);
        verify(payPalAddressDetailValidator).validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA);
        assertEquals(LINE_1, addressData.getLine1());
        assertEquals(LINE_2, addressData.getLine2());
        assertEquals(POSTAL_CODE, addressData.getPostalCode());
        assertEquals(LOCALITY, addressData.getTown());
        assertEquals(COUNTY_CODE, addressData.getCountry().getIsocode());
        assertEquals(COUNTY_CODE + "-" + ADMINISTRATIVE_AREA, addressData.getRegion().getIsocode());
        assertEquals(FIRST_NAME, addressData.getFirstName());
        assertEquals(LAST_NAME, addressData.getLastName());
    }

    @Test
    public void populateShouldSetRequiredFieldsWithoutLine2AndInvalidRegionAndCountry() {
        AddressData addressData = new AddressData();

        when(payPalAddressDetailValidator.validatePayPalCountryCode(COUNTY_CODE)).thenReturn(false);
        when(payPalAddressDetailValidator.validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA)).thenReturn(false);
        List<String> addressLines = new ArrayList<>();
        addressLines.add(LINE_1);
        when(applePayAddress.getAddressLines()).thenReturn(addressLines);

        unit.populate(applePayAddress, addressData);
        verify(payPalAddressDetailValidator).validatePayPalCountryCode(COUNTY_CODE);
        verify(payPalAddressDetailValidator).validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA);
        assertEquals(LINE_1, addressData.getLine1());
        assertEquals(POSTAL_CODE, addressData.getPostalCode());
        assertEquals(LOCALITY, addressData.getTown());
        assertNull(addressData.getCountry());
        assertNull(addressData.getRegion());
        assertEquals(FIRST_NAME, addressData.getFirstName());
        assertEquals(LAST_NAME, addressData.getLastName());
    }

    @Test
    public void populateShouldSetRequiredFieldsWhenLine2isNull() {
        AddressData addressData = new AddressData();

        when(payPalAddressDetailValidator.validatePayPalCountryCode(COUNTY_CODE)).thenReturn(true);
        when(payPalAddressDetailValidator.validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA)).thenReturn(true);
        List<String> addressLines = new ArrayList<>();
        addressLines.add(LINE_1);
        addressLines.add(null);
        when(applePayAddress.getAddressLines()).thenReturn(addressLines);

        unit.populate(applePayAddress, addressData);
        verify(payPalAddressDetailValidator).validatePayPalCountryCode(COUNTY_CODE);
        verify(payPalAddressDetailValidator).validatePayPalRegionCode(COUNTY_CODE, ADMINISTRATIVE_AREA);
        assertEquals(LINE_1, addressData.getLine1());
        assertNull(addressData.getLine2());
        assertEquals(POSTAL_CODE, addressData.getPostalCode());
        assertEquals(LOCALITY, addressData.getTown());
        assertEquals(COUNTY_CODE, addressData.getCountry().getIsocode());
        assertEquals(COUNTY_CODE + "-" + ADMINISTRATIVE_AREA, addressData.getRegion().getIsocode());
        assertEquals(FIRST_NAME, addressData.getFirstName());
        assertEquals(LAST_NAME, addressData.getLastName());
    }

}
