package com.mobify.astro.plugins;

import android.graphics.Color;
import android.view.View;

import com.mobify.astro.ActivityTestBase;
import com.mobify.astro.AstroPlugin;
import com.mobify.astro.PluginResolver;
import com.mobify.astro.TestPlugin;
import com.mobify.astro.dialogs.DialogManager;
import com.mobify.astro.messaging.EventManager;
import com.mobify.astro.messaging.MessageSender;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class ModalViewPluginTest extends ActivityTestBase {

    private ModalViewPlugin modalViewPlugin;
    private PluginResolver mockPluginResolver;
    private EventManager mockEventManager;
    private MessageSender mockMessageSender;
    private TestPlugin testPlugin;

    private DialogManager mockDialogManager;

    @Before
    public void setup() {

        mockPluginResolver = mock(PluginResolver.class);
        mockEventManager = mock(EventManager.class);
        mockMessageSender = mock(MessageSender.class);

        modalViewPlugin = new ModalViewPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);

        mockDialogManager = mock(DialogManager.class);
        modalViewPlugin.dialogManager = mockDialogManager;

        testPlugin = new TestPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
        when(mockPluginResolver.instanceForAddress(testPlugin.getInstanceAddress())).thenReturn(testPlugin);
        when(mockPluginResolver.instanceForAddress(modalViewPlugin.getInstanceAddress())).thenReturn(modalViewPlugin);
    }

    @Test
    public void testSetBackgroundColor() {
        String colorString = "#F7F7F7";
        modalViewPlugin.setBackgroundColor(colorString);

        assertEquals(Color.parseColor(colorString), modalViewPlugin.backgroundColor.intValue());
        verify(mockDialogManager).updateView(eq(modalViewPlugin.REQUEST_CODE), any(View.class));
    }

    @Test
    public void testSetBackgroundColorThrows() {
        try {
            modalViewPlugin.setBackgroundColor("bad color!!");
            fail();
        } catch (Exception e) {
            assertEquals(IllegalArgumentException.class, e.getClass());
        }
    }

    @Test
    public void testSetBackgroundColorNullThrows() {
        try {
            modalViewPlugin.setBackgroundColor(null);
            fail();
        } catch (Exception e) {
            assertEquals(NullPointerException.class, e.getClass());
        }
    }

    @Test
    public void testSetNullColorOnModalViewActivity() {
        // Test that no null pointer exception is thrown
        modalViewPlugin.backgroundColor = null;
        try {
            modalViewPlugin.setBackgroundColorOnView();
        } catch(NullPointerException e) {
            fail("NullPointException should not be thrown.");
        }
    }

    @Test
    public void testSetContentViewThenShow() throws Exception {
        modalViewPlugin.setContentView(testPlugin.getInstanceAddress());
        assertEquals(modalViewPlugin.contentView, testPlugin.getView());

        boolean didShow = modalViewPlugin.show(null);
        assertTrue(didShow);
        verify(mockDialogManager).updateView(eq(modalViewPlugin.REQUEST_CODE), any(View.class));
    }

    @Test
    public void testChangingContentView() throws Exception {
        AstroPlugin testPlugin2 = new TestPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
        when(mockPluginResolver.instanceForAddress(testPlugin2.getInstanceAddress())).thenReturn(testPlugin2);
        modalViewPlugin.setContentView(testPlugin.getInstanceAddress());
        modalViewPlugin.setContentView(testPlugin2.getInstanceAddress());

        assertNotSame(modalViewPlugin.contentView, testPlugin.getView());
        assertEquals(modalViewPlugin.contentView, testPlugin2.getView());
        verify(mockDialogManager, times(2)).updateView(eq(modalViewPlugin.REQUEST_CODE), any(View.class));
    }

    @Test
    public void testHide() throws Exception {
        modalViewPlugin.setContentView(testPlugin.getInstanceAddress());
        modalViewPlugin.show(null);
        boolean didHide = modalViewPlugin.hide(null);

        assertNotNull(modalViewPlugin.contentView);
        assertTrue(didHide);
        verify(mockDialogManager).removeModal(eq(modalViewPlugin.REQUEST_CODE));
    }
}
