package com.mobify.astro.plugins;

import android.os.Bundle;

import com.mobify.astro.ActivityTestBase;
import com.mobify.astro.AstroActivity;
import com.mobify.astro.PluginResolver;
import com.mobify.astro.dialogs.DialogManager;
import com.mobify.astro.messaging.EventManager;
import com.mobify.astro.messaging.MessageSender;
import com.mobify.astro.messaging.RpcResponse;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;

import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class AlertViewPluginTest extends ActivityTestBase {

    private AlertViewPlugin alertViewPlugin;
    private DialogManager mockDialogManager;
    private RpcResponse response;

    @Before
    public void setup() throws Exception {
        PluginResolver mockPluginResolver = mock(PluginResolver.class);
        EventManager mockEventManager = mock(EventManager.class);
        MessageSender mockMessageSender = mock(MessageSender.class);

        alertViewPlugin = new AlertViewPlugin(getActivity(), mockPluginResolver, mockEventManager, mockMessageSender);

        mockDialogManager = mock(DialogManager.class);
        alertViewPlugin.dialogManager = mockDialogManager;
    }

    @Test
    public void testSetTitle() {
        String title = "Title";
        alertViewPlugin.setTitle(title);
        assertEquals(title, alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_TITLE));
    }

    @Test
    public void testSetText() {
        String message = "Hello, This is a message that I want to have in the alert dialog";
        alertViewPlugin.setText(message);
        assertEquals(message, alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_MESSAGE));
    }

    @Test
    public void testShowWithoutButtons() {
        try {
            alertViewPlugin.show(response, null);
            fail("Should not be reached. No buttons added to the alert view should throw exception");
        } catch (Exception e) {
            assertThat(e, notNullValue());
        }
    }

    @Rule
    public ExpectedException thrown=ExpectedException.none();
    @Test
    public void testSetButtons() throws Exception {
        String okButtonLabel = "Ok Button";
        String cancelButtonLabel = "Cancel Button";

        assertNull(alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_OK_BUTTON));
        assertNull(alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_CANCEL_BUTTON));

        alertViewPlugin.addOkButton(okButtonLabel);

        assertEquals(okButtonLabel, alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_OK_BUTTON));
        assertNull(alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_CANCEL_BUTTON));

        alertViewPlugin.addCancelButton(cancelButtonLabel);

        assertEquals(okButtonLabel, alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_OK_BUTTON));
        assertEquals(cancelButtonLabel, alertViewPlugin.bundle.getString(AlertViewPlugin.KEY_CANCEL_BUTTON));

        alertViewPlugin.show(response, null);

        ArgumentCaptor<Bundle> argumentCaptor = ArgumentCaptor.forClass(Bundle.class);
        verify(mockDialogManager).showAlertDialog(argumentCaptor.capture(), any(AstroActivity.class), eq(response), eq(alertViewPlugin.REQUEST_CODE));
        Bundle actualBundle = argumentCaptor.getValue();
        assertEquals(okButtonLabel, actualBundle.getString(AlertViewPlugin.KEY_OK_BUTTON));
        assertEquals(cancelButtonLabel, actualBundle.getString(AlertViewPlugin.KEY_CANCEL_BUTTON));
    }
}
