package com.mobify.astro.plugins.headerbarplugin;

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

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

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

import static com.mobify.astro.helpers.AstroViewAsserts.assertViewHasDescendantView;
import static com.mobify.astro.helpers.AstroViewAsserts.assertViewHasDescendantWithPopulatedImageView;
import static com.mobify.astro.helpers.AstroViewAsserts.assertViewHasDescendantWithText;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class HeaderBarPluginTest extends ActivityTestBase {
    private PluginResolver mockPluginResolver;
    private EventManager mockEventManager;
    private MessageSender mockMessageSender;
    private HeaderBarPlugin headerBarPlugin;

    @Before
    public void setup() {
        mockPluginResolver = mock(PluginResolver.class);
        mockEventManager = mock(EventManager.class);
        mockMessageSender = mock(MessageSender.class);
        headerBarPlugin = new HeaderBarPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
    }

    @Test
    public void testGetView() {
        assertNotNull(headerBarPlugin.getView());
    }

    @Test
    public void testSetBackgroundColor() {
        headerBarPlugin.setBackgroundColor("#123456");

        ColorDrawable drawable = (ColorDrawable)headerBarPlugin.getView().getBackground();
        assertEquals(Color.parseColor("#123456"), drawable.getColor());
    }

    @Test
    public void testSetLeftIconVisibility() throws Exception {
        headerBarPlugin.setLeftTitle("Test Title", "123");
        headerBarPlugin.hideLeftIcon();
        assertEquals(View.GONE, headerBarPlugin.leftIcon.getVisibility());

        headerBarPlugin.showLeftIcon();
        assertEquals(View.VISIBLE, headerBarPlugin.leftIcon.getVisibility());
    }

    @Test
    public void testSetCenterIconVisibility() throws Exception {
        headerBarPlugin.setCenterTitle("Test Title", "123");
        headerBarPlugin.hideCenterIcon();
        assertEquals(View.GONE, headerBarPlugin.centerIcon.getVisibility());

        headerBarPlugin.showCenterIcon();
        assertEquals(View.VISIBLE, headerBarPlugin.centerIcon.getVisibility());
    }

    @Test
    public void testSetRightIconVisibility() throws Exception {
        headerBarPlugin.setRightTitle("Test Title", "123");
        headerBarPlugin.hideRightIcon();
        assertEquals(View.GONE, headerBarPlugin.rightIcon.getVisibility());

        headerBarPlugin.showRightIcon();
        assertEquals(View.VISIBLE, headerBarPlugin.rightIcon.getVisibility());
    }

    @Test
    public void testSetLeftTitle() throws Exception {
        headerBarPlugin.setLeftTitle("Test", "title");
        assertViewHasDescendantWithText(headerBarPlugin.leftIcon, "Test");
    }

    @Test
    public void testSetLeftIcon() throws Exception {
        headerBarPlugin.setLeftIcon("file:///test-image.png", "ignored", false);
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.leftIcon);
    }

    @Test
    public void testSetLeftPlugin() throws Exception {
        TestPlugin plugin = new TestPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
        when(mockPluginResolver.instanceForAddress(plugin.getInstanceAddress())).thenReturn(plugin);

        headerBarPlugin.setLeftPlugin(plugin.getInstanceAddress(), "ignored");

        assertViewHasDescendantView(headerBarPlugin.leftIcon, plugin.getView());
    }

    @Test
    public void testSetCenterTitle() throws Exception {
        headerBarPlugin.setCenterTitle("Test", "title");
        assertViewHasDescendantWithText(headerBarPlugin.centerIcon, "Test");
    }

    @Test
    public void testSetCenterIcon() throws Exception {
        headerBarPlugin.setCenterIcon("file:///test-image.png", "title", false);
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.centerIcon);
    }

    @Test
    public void testSetCenterPlugin() throws Exception {
        final TestPlugin plugin = new TestPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
        when(mockPluginResolver.instanceForAddress(plugin.getInstanceAddress())).thenReturn(plugin);

        headerBarPlugin.setCenterPlugin(plugin.getInstanceAddress(), "title");

        assertViewHasDescendantView(headerBarPlugin.centerIcon, plugin.getView());
    }

    @Test
    public void testSetRightTitle() throws Exception {
        headerBarPlugin.setRightTitle("Test", "title");
        assertViewHasDescendantWithText(headerBarPlugin.rightIcon, "Test");
    }

    @Test
    public void testSetRightIcon() throws Exception {
        headerBarPlugin.setRightIcon("file:///test-image.png", "ignored", false);
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.rightIcon);
    }

    @Test
    public void testSetRightPlugin() throws Exception {
        TestPlugin plugin = new TestPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);
        when(mockPluginResolver.instanceForAddress(plugin.getInstanceAddress())).thenReturn(plugin);

        headerBarPlugin.setRightPlugin(plugin.getInstanceAddress(), "ignored");

        assertViewHasDescendantView(headerBarPlugin.rightIcon, plugin.getView());
    }

    @Test
    public void testHeaderCoordination() throws Exception {
        // This test is a bit more involved. It tests pushing a few items on the header bar stack
        // and then popping them off.
        // Right now some assertions know a bit too much about the implementation, but I can't think
        // of a better way so I think this is better than nothing.
        headerBarPlugin.pushHeaderContent(HeaderContent.fromJson(mockPluginResolver, getActivity(), new JSONObject("{" +
                "  centerIcon: {" +
                "    id: \"title\"," +
                "    title: \"test\"" +
                "  }" +
                "}")));

        assertEquals(0, headerBarPlugin.leftIcon.getChildCount());
        assertViewHasDescendantWithText(headerBarPlugin.centerIcon, "test");
        assertEquals(0, headerBarPlugin.rightIcon.getChildCount());

        headerBarPlugin.pushHeaderContent(HeaderContent.fromJson(mockPluginResolver, getActivity(), new JSONObject("{" +
                "  leftIcon: {" +
                "    id: \"cart\"," +
                "    imageUrl: \"file:///test-image.png\"" +
                "  }" +
                "}")));
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.leftIcon);
        assertEquals(0, headerBarPlugin.centerIcon.getChildCount());
        assertEquals(0, headerBarPlugin.rightIcon.getChildCount());

        headerBarPlugin.pushHeaderContent(HeaderContent.fromJson(mockPluginResolver, getActivity(), new JSONObject("{" +
                "  rightIcon: {" +
                "    id: \"cart\"," +
                "    imageUrl: \"file:///test-image.png\"" +
                "  }" +
                "}")));
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.leftIcon); // Back button
        assertEquals(0, headerBarPlugin.centerIcon.getChildCount());
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.rightIcon);

        headerBarPlugin.popHeaderContent();
        assertViewHasDescendantWithPopulatedImageView(headerBarPlugin.leftIcon);
        assertEquals(0, headerBarPlugin.centerIcon.getChildCount());
        assertEquals(0, headerBarPlugin.rightIcon.getChildCount());

        headerBarPlugin.popHeaderContent();
        assertEquals(0, headerBarPlugin.leftIcon.getChildCount());
        assertViewHasDescendantWithText(headerBarPlugin.centerIcon, "test");
        assertEquals(0, headerBarPlugin.rightIcon.getChildCount());
    }

    @Test
    public void testSubscribedToLocaleUpdates() {
        verify(headerBarPlugin.localizationUtilities).addLocaleChangedListener(headerBarPlugin);
    }
}
