package com.braintree.paypal.converters.impl;

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

import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.core.model.c2l.CountryModel;
import de.hybris.platform.core.model.c2l.RegionModel;
import de.hybris.platform.core.model.user.AddressModel;
import de.hybris.platform.core.model.user.CustomerModel;
import de.hybris.platform.payment.dto.BillingInfo;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

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

    private static final String FIRST_NAME = "FIRST_NAME";
    private static final String LAST_NAME = "LAST_NAME";
    private static final String STREET_NAME = "STREET_NAME";
    private static final String STREET_NUMBER = "STREET_NUMBER";
    private static final String TOWN = "CITY";
    private static final String POSTAL_CODE = "POSTAL_CODE";
    private static final String REGION_ICO_CODE = "REGION_ICO_CODE";
    private static final String COUNTRY_ISO_CODE = "COUNTRY_ISO_CODE";
    private static final String EMAIL = "EMAIL";

    @InjectMocks
    private final BraintreeBillingAddressConverter unit = new BraintreeBillingAddressConverter();

    @Mock
    private AddressModel addressModel;
    @Mock
    private RegionModel regionModel;
    @Mock
    private CountryModel countryModel;

    @Before
    public void setUp() {
        when(addressModel.getFirstname()).thenReturn(FIRST_NAME);
        when(addressModel.getLastname()).thenReturn(LAST_NAME);
        when(addressModel.getStreetname()).thenReturn(STREET_NAME);
        when(addressModel.getStreetnumber()).thenReturn(STREET_NUMBER);
        when(addressModel.getTown()).thenReturn(TOWN);
        when(addressModel.getPostalcode()).thenReturn(POSTAL_CODE);
        when(addressModel.getRegion()).thenReturn(regionModel);
        when(addressModel.getCountry()).thenReturn(countryModel);
        when(regionModel.getIsocodeShort()).thenReturn(REGION_ICO_CODE);
        when(countryModel.getIsocode()).thenReturn(COUNTRY_ISO_CODE);
    }

    @Test
    public void convertShouldParseAddressAndGetEmailFromAddress() {
        when(addressModel.getEmail()).thenReturn(EMAIL);
        when(addressModel.getRegion()).thenReturn(null);
        when(addressModel.getCountry()).thenReturn(null);

        final BillingInfo billingInfo = unit.convert(addressModel);

        assertNotNull(billingInfo);
        assertEquals(FIRST_NAME, billingInfo.getFirstName());
        assertEquals(LAST_NAME, billingInfo.getLastName());
        assertEquals(STREET_NAME, billingInfo.getStreet1());
        assertEquals(STREET_NUMBER, billingInfo.getStreet2());
        assertEquals(TOWN, billingInfo.getCity());
        assertEquals(POSTAL_CODE, billingInfo.getPostalCode());
        assertNull(billingInfo.getState());
        assertNull(billingInfo.getCountry());
        assertEquals(EMAIL, billingInfo.getEmail());
    }

    @Test
    public void convertShouldParseAddressAndGetEmailFromOwnerCustomer() {
        final CustomerModel customerModel = mock(CustomerModel.class);

        when(addressModel.getOwner()).thenReturn(customerModel);
        when(customerModel.getContactEmail()).thenReturn(EMAIL);

        final BillingInfo billingInfo = unit.convert(addressModel);

        assertNotNull(billingInfo);
        assertEquals(FIRST_NAME, billingInfo.getFirstName());
        assertEquals(LAST_NAME, billingInfo.getLastName());
        assertEquals(STREET_NAME, billingInfo.getStreet1());
        assertEquals(STREET_NUMBER, billingInfo.getStreet2());
        assertEquals(TOWN, billingInfo.getCity());
        assertEquals(POSTAL_CODE, billingInfo.getPostalCode());
        assertEquals(REGION_ICO_CODE, billingInfo.getState());
        assertEquals(COUNTRY_ISO_CODE, billingInfo.getCountry());
        assertEquals(EMAIL, billingInfo.getEmail());
    }

    @Test
    public void shouldReturnEmptyBillingInfoWhenAddressIsNull(){
        final BillingInfo billingInfo = unit.convert(null);

        assertNotNull(billingInfo);
        assertNull(billingInfo.getFirstName());
        assertNull(billingInfo.getLastName());
        assertNull(billingInfo.getStreet1());
        assertNull(billingInfo.getStreet2());
        assertNull(billingInfo.getCity());
        assertNull(billingInfo.getPostalCode());
        assertNull(billingInfo.getState());
        assertNull(billingInfo.getCountry());
        assertNull(billingInfo.getEmail());

    }

}
