package com.avaya.zephyr.services.multichanbroadcast;

import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.mockito.Mockito.mock;
import static org.powermock.api.easymock.PowerMock.createMock;
import static org.powermock.api.easymock.PowerMock.expectLastCall;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.mockStatic;
import static org.powermock.api.easymock.PowerMock.replayAll;
import static org.powermock.api.easymock.PowerMock.verifyAll;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.avaya.collaboration.businessdata.api.ServiceData;
import com.avaya.collaboration.dal.factory.CollaborationDataFactory;
import com.avaya.collaboration.service.activity.ServiceActivityData;
import com.avaya.collaboration.service.activity.ServiceActivityDataFactory;
import com.avaya.collaboration.util.logger.Logger;
import com.avaya.zephyr.platform.dal.api.ServiceDescriptor;
import com.avaya.zephyr.platform.dal.api.ServiceUtil;
import com.avaya.zephyr.services.multichanbroadcast.announcementcall.MultiChanBroadcastAnnouncementSender;
import com.avaya.zephyr.services.multichanbroadcast.email.MultiChanBroadcastEmailSender;
import com.avaya.zephyr.services.multichanbroadcast.sms.MultiChanBroadcastSmsSender;

@RunWith(PowerMockRunner.class)
@PrepareForTest(
{ ServiceUtil.class, CollaborationDataFactory.class,
        MultiChanBroadcastServlet.class, ServiceActivityDataFactory.class })
public class MultiChanBroadcastServletTest
{
    private MultiChanBroadcastServlet multiChanBroadcastServletTest;
    private Logger mockLogger;
    private PrintWriter mockPrinterWriter;
    private HttpServletRequest mockHttpServletRequest;
    private HttpServletResponse mockHttpServletResponse;
    ServiceActivityData serviceActivityData;
    private ServiceDescriptor mockServiceDescriptor;
    private ServiceData mockServiceData;
    private MultiChanBroadcastEmailSender mockMultiChanBroadcastEmailSender;
    private MultiChanBroadcastSmsSender mockMultiChanBroadcastSmsSender;

    @Before
    public void setUpMockCommon() throws Exception
    {
        mockLogger = createMock(Logger.class);
        mockPrinterWriter = createMock(PrintWriter.class);
        mockHttpServletRequest = createMock(HttpServletRequest.class);
        mockHttpServletResponse = createMock(HttpServletResponse.class);

        mockServiceDescriptor = createMock(ServiceDescriptor.class);
        mockServiceData = createMock(ServiceData.class);
        mockMultiChanBroadcastEmailSender =
                createMock(MultiChanBroadcastEmailSender.class);
        mockMultiChanBroadcastSmsSender =
                createMock(MultiChanBroadcastSmsSender.class);

        ServiceActivityData serviceActivityData = mock(ServiceActivityData.class);
        PowerMockito.mockStatic(ServiceActivityDataFactory.class);
        PowerMockito.when(ServiceActivityDataFactory.createServicActivityData()).thenReturn(
                serviceActivityData);

        multiChanBroadcastServletTest = new MultiChanBroadcastServlet(mockLogger);

        expect(mockHttpServletResponse.getWriter()).andReturn(mockPrinterWriter);
        mockLogger.info("doPost");
        expectLastCall();
        mockHttpServletResponse.setContentType("text/plain");
        expectLastCall();
    }

    private void setUpMockServiceData() throws Exception
    {
        mockStatic(ServiceUtil.class);
        expect(ServiceUtil.getServiceDescriptor()).andReturn(mockServiceDescriptor);
        mockStatic(CollaborationDataFactory.class);
        expect(CollaborationDataFactory.getServiceData(mockServiceDescriptor.getName(),
                mockServiceDescriptor.getVersion())).andReturn(mockServiceData);
    }

    private void setUpMockServiceDataNull() throws Exception
    {
        mockStatic(ServiceUtil.class);
        expect(ServiceUtil.getServiceDescriptor()).andReturn(null);
        mockLogger.error((String) anyObject());
        expectLastCall();
        mockPrinterWriter.println((String) anyObject());
        mockHttpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        expectLastCall();
    }

    private void setupMockEmailSender(boolean sent) throws Exception
    {
        expectNew(MultiChanBroadcastEmailSender.class, mockServiceData, mockHttpServletRequest,
                mockPrinterWriter)
                .andReturn(mockMultiChanBroadcastEmailSender);
        expect(mockMultiChanBroadcastEmailSender.sendEmail()).andReturn(sent);
    }

    private void setupMockAnnouncementSender(boolean sent) throws Exception
    {
        final MultiChanBroadcastAnnouncementSender mockMultiChanBroadcastAnnouncementSender =
                createMock(MultiChanBroadcastAnnouncementSender.class);
        expectNew(MultiChanBroadcastAnnouncementSender.class, mockServiceData,
                mockHttpServletRequest,
                mockPrinterWriter)
                .andReturn(mockMultiChanBroadcastAnnouncementSender);
        expect(mockMultiChanBroadcastAnnouncementSender.sendAnnouncement()).andReturn(sent);
    }

    private void setupMockSmsSender(boolean sent) throws Exception
    {
        expectNew(MultiChanBroadcastSmsSender.class, mockServiceData, mockHttpServletRequest,
                mockPrinterWriter)
                .andReturn(mockMultiChanBroadcastSmsSender);
        expect(mockMultiChanBroadcastSmsSender.sendSms()).andReturn(sent);
    }

    @Test
    public void testServiceDataNull() throws Exception
    {

        mockLogger.info("MCB : Activity Increment : 0");
        mockLogger.info("MCB : Activity Decrement : 0");
        // Test Info

        // Test Data

        // Setup mocks
        setUpMockServiceDataNull();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastServletTest.doPost(mockHttpServletRequest, mockHttpServletResponse);
        verifyAll();
    }

    @Test
    public void testNoEmailAnnouncementSms() throws Exception
    {
        mockLogger.info("MCB : Activity Increment : 0");
        mockLogger.info("MCB : Activity Decrement : 0");
        // Test Info

        // Test Data

        // Setup mocks
        setUpMockServiceData();
        setupMockEmailSender(false);
        setupMockAnnouncementSender(false);
        setupMockSmsSender(false);
        mockHttpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastServletTest.doPost(mockHttpServletRequest, mockHttpServletResponse);
        verifyAll();
    }

    @Test
    public void testEmailSend() throws Exception
    {
        mockLogger.info("MCB : Activity Increment : 0");
        mockLogger.info("MCB : Activity Decrement : 0");
        // Test Info

        // Test Data

        // Setup mocks
        setUpMockServiceData();
        setupMockEmailSender(true);
        setupMockAnnouncementSender(false);
        setupMockSmsSender(false);
        mockHttpServletResponse.setStatus(HttpServletResponse.SC_OK);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastServletTest.doPost(mockHttpServletRequest, mockHttpServletResponse);
        verifyAll();
    }

    @Test
    public void testAnncSend() throws Exception
    {
        mockLogger.info("MCB : Activity Increment : 0");
        mockLogger.info("MCB : Activity Decrement : 0");
        // Test Info

        // Test Data

        // Setup mocks
        setUpMockServiceData();
        setupMockEmailSender(false);
        setupMockAnnouncementSender(true);
        setupMockSmsSender(false);
        mockHttpServletResponse.setStatus(HttpServletResponse.SC_OK);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastServletTest.doPost(mockHttpServletRequest, mockHttpServletResponse);
        verifyAll();
    }

    @Test
    public void testSmsSend() throws Exception
    {
        mockLogger.info("MCB : Activity Increment : 0");
        mockLogger.info("MCB : Activity Decrement : 0");
        // Test Info

        // Test Data

        // Setup mocks
        setUpMockServiceData();
        setupMockEmailSender(false);
        setupMockAnnouncementSender(false);
        setupMockSmsSender(true);
        mockHttpServletResponse.setStatus(HttpServletResponse.SC_OK);
        expectLastCall();

        // Replay, Execute, and Verify
        replayAll();
        multiChanBroadcastServletTest.doPost(mockHttpServletRequest, mockHttpServletResponse);
        verifyAll();
    }
}
