package com.mobify.astro;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import com.mobify.astro.messaging.EventManager;
import com.mobify.astro.messaging.MessageSender;
import com.mobify.astro.utilities.LocalizationUtilities;
import com.mobify.astro.utilities.LocalizationUtilitiesTest;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

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

@RunWith(AndroidJUnit4.class)
public class LocalizationWrapperTests {

    private LocalizationUtilitiesTest.StubLocaleChangedListener stubLocaleChangedListener;
    private LocalizationUtilities localizationUtilities;
    private LocalizationWrapper localizationWrapper;

    @Rule
    public final ExpectedException exception = ExpectedException.none();

    @Before
    public void setUp() {
        stubLocaleChangedListener = new LocalizationUtilitiesTest.StubLocaleChangedListener();
        localizationUtilities = new LocalizationUtilities(InstrumentationRegistry.getTargetContext());
        localizationUtilities.addLocaleChangedListener(stubLocaleChangedListener);

        EventManager mockEventManager = mock(EventManager.class);
        MessageSender mockMessageSender = mock(MessageSender.class);
        localizationWrapper = new LocalizationWrapper(localizationUtilities, mockEventManager, mockMessageSender);
    }

    @Test
    public void testSetLocaleRpc() throws Exception {
        JSONObject locale = new JSONObject();
        locale.put("country", "fr");
        locale.put("language", "fr");
        localizationWrapper.setLocale(locale);
        assertEquals("fr", localizationUtilities.getLanguage());
        assertEquals("FR", localizationUtilities.getCountry());
        assertEquals(1, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testSetLocaleNoLanguage() throws Exception {
        JSONObject locale = new JSONObject();
        locale.put("country", "fr");
        exception.expect(JSONException.class);
        localizationWrapper.setLocale(locale);
        assertEquals(0, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testSetLocaleNoCountry() throws Exception {
        JSONObject locale = new JSONObject();
        locale.put("language", "fr");
        exception.expect(JSONException.class);
        localizationWrapper.setLocale(locale);
        assertEquals(0, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testGetLocaleRpc() throws JSONException {
        localizationUtilities.setCountry("ca");
        localizationUtilities.setLanguage("en");
        JSONObject localeJson = localizationWrapper.getLocale();
        assertEquals("CA", localeJson.getString("country"));
        assertEquals("en", localeJson.getString("language"));
        assertEquals(2, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testSetLanguageRpc() {
        localizationWrapper.setLanguage("de");
        assertEquals("de", localizationUtilities.getLanguage());
        assertEquals(1, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testGetLanguageRpc() {
        localizationUtilities.setLanguage("cs");
        assertEquals("cs", localizationWrapper.getLanguage());
        assertEquals(1, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testSetCountryRpc() {
        localizationWrapper.setCountry("dk");
        assertEquals("DK", localizationWrapper.getCountry());
        assertEquals(1, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testGetCountryRpc() {
        localizationUtilities.setCountry("gb");
        assertEquals("GB", localizationWrapper.getCountry());
        assertEquals(1, stubLocaleChangedListener.callCount);
    }

    @Test
    public void testTranslateRpc() {
        localizationUtilities.setLanguage("en");
        assertEquals("Basic test result", localizationWrapper.translate("test_basic"));
        localizationUtilities.setLanguage("ar");
        assertEquals("Basic test result (العربية)", localizationWrapper.translate("test_basic"));
        assertEquals(2, stubLocaleChangedListener.callCount);
    }
}
