/*
 * Copyright (c) Smals
 */
package be.ehealth.businessconnector.ehbox.v3.session;

import java.util.ArrayList;
import java.util.List;

import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.businessconnector.ehbox.api.domain.Addressee;
import be.ehealth.businessconnector.ehbox.api.domain.DocumentMessage;
import be.ehealth.businessconnector.ehbox.api.domain.NewsMessage;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestDataBuilder;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestUtilities;
import be.ehealth.businessconnector.ehbox.v3.builders.BuilderFactory;
import be.ehealth.technicalconnector.exception.ConnectorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.session.Session;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetMessageListResponseType;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.Message;
import be.fgov.ehealth.ehbox.core.v3.BoxIdType;
import be.fgov.ehealth.ehbox.publication.protocol.v3.SendMessageResponse;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;


/**
 * abstract superclass for integration tests.
 * 
 * @author EHP
 * 
 */
public abstract class AbstractEhboxV3ServiceIntegration {

    private static final String TEST_PROPERTY_FILE = "/be.ehealth.businessconnector.ehboxv3.test.properties";

    private static final Logger LOG = LoggerFactory.getLogger(AbstractEhboxV3ServiceIntegration.class);

    private static BoxIdType alternativeMailBox;


    /**
     * @return the alternativeMailBox
     */
    public static BoxIdType getAlternativeMailBox() {
        return alternativeMailBox;
    }

    private static String oldNewsMessageIdDefaultBox;

    private static String newsMessageIdDefaultBox;

    private static String documentMessageIdDefaultBox;

    private static String oldNewsMessageIdAlternativeBox;

    private static String newsMessageIdAlternativeBox;

    private static String documentMessageIdAlternativeBox;

    private static boolean isDoctorTest;

    public static void initializeMailboxesInKnownCondition() throws Exception {
        SessionInitializer.init(TEST_PROPERTY_FILE);
        isDoctorTest = EhboxTestUtilities.isDoctorTest(TEST_PROPERTY_FILE);
        // current test setup doesn't work for organisations
        Assume.assumeTrue(isDoctorTest);
        alternativeMailBox = EhboxTestDataBuilder.getEhboxSender();
        resetAllMessageIds();
        initializeMailbox(alternativeMailBox);
        initializeMailbox(null);
    }

    @AfterClass
    public static void tearDown() throws Exception {
        Session.getInstance().unloadSession();
    }

    public static String getCreatedNewsIdForMailbox(BoxIdType mailBox) {
        if (mailBox == null) {
            return newsMessageIdDefaultBox;
        } else {
            return newsMessageIdAlternativeBox;
        }
    }

    public static String getCreatedDocumentIdForMailbox(BoxIdType mailBox) {
        if (mailBox == null) {
            return documentMessageIdDefaultBox;
        } else {
            return documentMessageIdAlternativeBox;
        }
    }

    public static String getCreatedOldNewsIdForMailbox(BoxIdType mailBox) {
        if (mailBox == null) {
            return oldNewsMessageIdDefaultBox;
        } else {
            return oldNewsMessageIdAlternativeBox;
        }
    }

    public List<String> getAllCreatedMessageIds() {
        ArrayList<String> result = new ArrayList<String>();
        result.add(documentMessageIdAlternativeBox);
        result.add(documentMessageIdDefaultBox);
        result.add(newsMessageIdAlternativeBox);
        result.add(newsMessageIdDefaultBox);
        return result;
    }

    /**
     * 
     */
    private static void resetAllMessageIds() {
        oldNewsMessageIdDefaultBox = null;
        newsMessageIdDefaultBox = null;
        documentMessageIdDefaultBox = null;
        oldNewsMessageIdAlternativeBox = null;
        newsMessageIdAlternativeBox = null;
        documentMessageIdAlternativeBox = null;
    }


    /**
     * @param boxId
     * @throws Exception
     */
    private static void initializeMailbox(BoxIdType boxId) throws Exception {

        // send 2 newsMessages
        Addressee addresseeForBoxIdType = EhboxTestUtilities.mapBoxIdTypeToAddressee(boxId);
        NewsMessage<Message> fullExampleNewsMessage = EhboxTestDataBuilder.buildFullExampleNewsMessage(true, true, addresseeForBoxIdType);
        fullExampleNewsMessage.getDocument().setTitle("ConnectorTest : originalNews:boxId=" + boxId);
        SendMessageResponse sendMessageResponseNews1 = ServiceFactory.getEhealthBoxServiceV3().sendMessage(BuilderFactory.getSendMessageBuilder().buildMessage(fullExampleNewsMessage));
        String publicationId = sendMessageResponseNews1.getSentPublicationId();
        String oldNewsId = sendMessageResponseNews1.getId();
        fullExampleNewsMessage.getDocument().setTitle("ConnectorTest : changedNewsTitle:boxId=" + boxId);
        SendMessageResponse sendMessageResponseNewsUpdate = ServiceFactory.getEhealthBoxServiceV3().sendMessage(BuilderFactory.getSendMessageBuilder().buildMessage(fullExampleNewsMessage));
        String newsId = sendMessageResponseNewsUpdate.getId();
        Assert.assertEquals(publicationId, sendMessageResponseNewsUpdate.getSentPublicationId());


        DocumentMessage<Message> fullExampleDocumentMessage = EhboxTestDataBuilder.buildFullExampleDocumentMessage(true, true, addresseeForBoxIdType);
        SendMessageResponse sendMessageResponseDocument = ServiceFactory.getEhealthBoxServiceV3().sendMessage(BuilderFactory.getSendMessageBuilder().buildMessage(fullExampleDocumentMessage));
        String documentId = sendMessageResponseDocument.getId();

        if (boxId == null) {
            newsMessageIdDefaultBox = newsId;
            documentMessageIdDefaultBox = documentId;
            oldNewsMessageIdDefaultBox = oldNewsId;
        } else {
            newsMessageIdAlternativeBox = newsId;
            documentMessageIdAlternativeBox = documentId;
            oldNewsMessageIdAlternativeBox = oldNewsId;
        }
        EhboxTestUtilities.waitForProcessing(1500);
        List<String> messagesInInbox = getListOfMessagesForSource("INBOX", boxId);
        Assert.assertFalse("there should be some messages in the inbox", messagesInInbox.isEmpty());
        Assert.assertTrue("newsId should be in inbox", messagesInInbox.contains(newsId));
        Assert.assertTrue("documentId should be in inbox", messagesInInbox.contains(documentId));


    }

    /**
     * @param source
     * @throws ConnectorException
     * @throws TechnicalConnectorException
     */
    protected static List<String> getListOfMessagesForSource(String source, BoxIdType ehboxToUse) throws TechnicalConnectorException, ConnectorException {
        GetMessageListResponseType messageList = ServiceFactory.getEhealthBoxServiceV3().getMessageList(BuilderFactory.getRequestBuilder().createGetMessagesListRequest(source, 1, 100, ehboxToUse));
        ArrayList<String> listOfMessageIds = getListOfMessageIdsFromResponse(messageList);
        logMessageList(source, messageList.getMessages());
        return listOfMessageIds;
    }


    /**
     * @param source
     * @param messages
     */
    protected static void logMessageList(String source, List<Message> messages) {
        for (Message message : messages) {
            EhboxTestUtilities.logMessage(message);
        }

    }

    /**
     * @param messageList
     * @return
     */
    public static ArrayList<String> getListOfMessageIdsFromResponse(GetMessageListResponseType messageList) {
        ArrayList<String> listOfMessageIds = new ArrayList<String>();
        for (Message message : messageList.getMessages()) {
            listOfMessageIds.add(message.getMessageId());
        }
        logMessageList(messageList.getSource(), messageList.getMessages());
        return listOfMessageIds;
    }


    /**
     * @param source
     * @param fullListOfIds
     */
    public static void logList(String source, List<String> fullListOfIds) {
        StringBuilder sb = new StringBuilder(source + " :");
        for (String messageId : fullListOfIds) {
            sb.append(messageId).append(" ");
        }
        LOG.debug("logList : " + sb.toString());
    }


    /**
     * @param messageId
     * @param msg
     */
    public void checkMessageIdEqualsCreatedMessage(String messageId, be.ehealth.businessconnector.ehbox.api.domain.Message<Message> msg, BoxIdType mailBoxToUse) {
        if (msg instanceof NewsMessage<?>) {
            messageId.equals(getCreatedNewsIdForMailbox(mailBoxToUse));
        } else if (msg instanceof DocumentMessage<?>) {
            messageId.equals(getCreatedDocumentIdForMailbox(mailBoxToUse));
        }
    }

}
