package com.mobify.astro;

import android.annotation.TargetApi;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.support.test.annotation.UiThreadTest;
import android.support.test.rule.ActivityTestRule;

import com.mobify.astro.messaging.EventManager;
import com.mobify.astro.messaging.MessageSender;

import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.util.List;

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

public class AstroApplicationTest {

    @Rule
    public ActivityTestRule mActivityRule = new ActivityTestRule<>(TestActivity.class,
            /* initialTouchMode */ true,
            /* launchActivity */ false);

    AstroApplication application;
    PluginManager pluginManager;
    Intent launchIntent = new Intent(Intent.ACTION_MAIN);
    EventManager mockEventManager;
    MessageSender mockMessageSender;

    private AstroActivity getActivity() {
        return (AstroActivity)mActivityRule.getActivity();
    }

    @Before
    public void setup() {
        mActivityRule.launchActivity(launchIntent);
        mockEventManager = mock(EventManager.class);
        mockMessageSender = mock(MessageSender.class);

        application = new AstroApplication(getActivity(), mockEventManager, mockMessageSender);
        pluginManager = getActivity().pluginManager;
    }

    @Test
    public void testSetMainViewPlugin() throws Throwable {
        AstroPlugin plugin = mock(AstroPlugin.class);

        String testInstanceName = "testInstance";
        when(plugin.getInstanceAddress()).thenReturn(testInstanceName);

        AstroActivity activityMock = mock(AstroActivity.class);
        AstroApplication testApplication = new AstroApplication(activityMock, new EventManager(), mockMessageSender);

        testApplication.setMainViewPlugin(plugin.getInstanceAddress());

        verify(activityMock).setMainViewPlugin(testInstanceName);
    }

    @Test
    public void testIsFreshLaunch() {
        assertFalse(application.isResuming());
    }

    @Test
    public void testGetStartUriNull() {

        // The activity wasn't started by and intent with a URI
        String uri = application.getStartUri();
        assertNull(uri);
    }

    @Test
    public void testGetValidIntents() {
        List<Intent> validIntents = application.getValidIntents("http://www.mobify.com");

        for (Intent validIntent : validIntents) {
            if (validIntent.getPackage().equals(getActivity().getPackageName())) {
                fail("Package not successfully removed from list of valid intents");
                return;
            }
        }
    }

    @Test
    public void testGetAppInformation() throws JSONException, AstroApplication.AstroApplicationException {
        String serial = Settings.Secure.getString(getActivity().getContentResolver(), Settings.Secure.ANDROID_ID);
        JSONObject results = application.getAppInformation();

        assertEquals(serial, results.getString("installationID"));
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Test
    @UiThreadTest
    public void testSetStatusBarColor() {
        String redColor = "#FF0000";
        application.setStatusBarColor(redColor);

        // Set status bar color is a no-op in Astro for version below Lollipop
        // since those android versions don't support the APIs we require.
        // In these versions, getStatusBarColor will explode.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            assertEquals(Color.RED, getActivity().getWindow().getStatusBarColor());
        }
    }

    @Test
    public void testSetBackgroundColor() {
        String redColor = "#FF0000";
        AstroActivity activityMock = mock(AstroActivity.class);
        AstroApplication testApplication = new AstroApplication(activityMock, new EventManager(), mockMessageSender);

        testApplication.setBackgroundColor(redColor);

        verify(activityMock).setBackgroundColor(Color.parseColor(redColor));
    }

    @Test
    public void testCloseApp() {
        AstroActivity activityMock = mock(AstroActivity.class);
        AstroApplication testApplication = new AstroApplication(activityMock, new EventManager(), mockMessageSender);

        testApplication.closeApp();

        verify(activityMock).moveTaskToBack(false);
    }
}