/*
 * Copyright (c) eHealth
 */
using System;
using System.Threading;
using be.ehealth.businessconnector.ehbox.api.domain;
using ikvm.extensions;
using java.lang;
using NUnit.Framework;
using java.io;
using java.util;
using javax.xml.bind;
using org.apache.commons.lang3;
using org.joda.time;
using sun.security.action;
using be.fgov.ehealth.technicalconnector.tests.session;
using be.ehealth.technicalconnector.exception;
using be.ehealth.businessconnector.ehbox.v3.session;
using domain = be.ehealth.businessconnector.ehbox.api.domain;
using be.ehealth.businessconnector.ehbox.api.utils;
using be.ehealth.businessconnector.ehbox.v3.builders;
using be.ehealth.technicalconnector.config;
using be.ehealth.technicalconnector.utils;
using be.fgov.ehealth.commons.protocol.v1;
using consultation = be.fgov.ehealth.ehbox.consultation.protocol.v3;
using be.fgov.ehealth.ehbox.core.v3;
using be.fgov.ehealth.ehbox.publication.protocol.v3;
using be.ehealth.businessconnector.ehbox.v3;
using be.ehealth.technicalconnector.session;
using be.fgov.ehealth.ehbox.consultation.protocol.v3;

/**
 * eHealthBox Service Integration Tests This test shows the use of the eHealthBox Service through the use of the Business Connector.
 * 
 * The tests below use the Session Management Service to manage the session and SAML/STS token. The eHealthBox of the test user specified in
 * the business connector property file is used, these tests expect that this is set to a valid INSS of a citizen.
 */
namespace be.ehealth.businessconnector.ehboxv3.service
{
    [TestFixture]
    public class EhboxV3ServiceConsultationIntegrationTest:AbstractEhboxV3ServiceIntegration
    {
        private BoxIdType mailBoxToUse = null;

        /**
         * Initialise messageID if not already done
         * 
         * @throws Exception
         */
        [SetUp]
        public void init(){
            AbstractEhboxV3ServiceIntegration.initializeMailboxesInKnownCondition();
        }
        [TearDown]
        public void unloadSession() {
            Session.getInstance().unloadSession();
        }

        /**
         * @param mailBoxToUse
         */
        public EhboxV3ServiceConsultationIntegrationTest(BoxIdType mailBoxToUse) {
            this.mailBoxToUse = mailBoxToUse;
        }

        /**
         * Test the getBoxInfo operation from the eHealthBox Service through the use of the Business Connector. The getBoxInfo retrieves general
         * info about an eHealthBox
         * 
         * The following main steps are done: - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */
        [Test]
        public void testGetBoxInfo() {
            /*
             * Invoke the business connector framework's eHealthBox's getBoxInfo operation
             */
            GetBoxInfoResponse response = ServiceFactory.getEhealthBoxServiceV3().getBoxInfo(BuilderFactory.getRequestBuilder().createBoxInfoRequest(mailBoxToUse));

            /*
             * Verify the response
             */
            // check if there are no errors
            Assert.AreEqual("100", response.getStatus().getCode());
            // check if there is any content
            Assert.IsNotNull(response.getBoxId());
        }


        /**
         * Test the getMessageList operation from the eHealthBox Service through the use of the Business Connector. This test retrieves the
         * messageId's of the message's in a given folder, correct values for the folder are: INBOX | SENT | BIN
         * 
         * The following main steps are done: - Create the parameters of the new message - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */
        [Test]
        public void testGetMessageList() {
            /*
             * Create the parameters of the new message
             */
            // set the folder (INBOX | SENTBOX | BININBOX | BINSENTBOX)
            string source = "INBOX";

            GetMessageListResponseType response = ServiceFactory.getEhealthBoxServiceV3().getMessageList(BuilderFactory.getRequestBuilder().createGetMessagesListRequest(source));


            /*
             * Verify the response
             */
            // check if there are no errors
            Assert.AreEqual("100", response.getStatus().getCode());
            // check if a messageId has been returned
            Assert.IsNotNull(response.getMessages());
            // print out the messageId's for the given folder
            java.util.List list = response.getMessages();
            
            for(int i = 0; i < list.size();i++) {
                // JAXB.marshal(message, System.out);
                consultation.Message message = (consultation.Message) list.get(i);
                string messageId = message.getMessageId();
                try {
                    domain.Message msg = BuilderFactory.getConsultationMessageBuilder().buildMessage(message);
                    checkMessageIdEqualsCreatedMessage(messageId, msg, mailBoxToUse);
                } catch (java.lang.Exception e) {
                    EhboxTestUtilities.logStackTrace(e);
                }
            }
        }

        /**
         * Test the getFullMessage operation from the eHealthBox Service through the use of the Business Connector. This test retrieves a full
         * message based on a given messageId's. Usually the messageId is retrieved first from the getMessageList operation.
         * 
         * The following main steps are done: - Create the parameters of the new message - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */

        [Test]
        public void testGetFullMessage(){
            /*
             * Create the parameters of the new message
             */
            try {
    
                /*
                 * Invoke the business connector framework's eHealthBox's getFullMessage operation
                 */
    
                MessageRequestType request = new MessageRequestType();
    
                GetMessagesListRequest listRequest = new GetMessagesListRequest();
                listRequest.setSource("INBOX");
                GetMessageListResponseType listResponse = ServiceFactory.getEhealthBoxServiceV3().getMessageList(listRequest);
                java.util.List messages = listResponse.getMessages();
                Assert.IsFalse(messages.isEmpty(),"no messages found");
                request.setSource("INBOX");
                request.setMessageId(getMessageId(messages));
                EhboxTestUtilities.waitForProcessing();
                GetFullMessageResponse response = ServiceFactory.getEhealthBoxServiceV3().getFullMessage(request);
    
                /*
                 * Verify the response
                 */
    
                // check if the message has been returned
                Assert.IsNotNull(response.getMessage().getPublicationId());
                be.ehealth.businessconnector.ehbox.api.domain.Message msg = BuilderFactory.getConsultationMessageBuilder().buildFullMessage(response);
                if (msg.GetType() == typeof(DocumentMessage)) {
                    DocumentMessage message = (DocumentMessage) msg;
                } else if (msg.GetType() == typeof(NewsMessage)) {
                    NewsMessage message = (NewsMessage) msg;
                    Assert.IsNotNull(message);
                }
            } catch (java.lang.Exception e) {
                EhboxTestUtilities.logStackTrace(e);
                Assert.Fail(e.getMessage());
            }
        }

    
        /**
         * Test the getFullMessage operation from the eHealthBox Service through the use of the Business Connector. This test retrieves a full
         * message based on a given messageId's. Usually the messageId is retrieved first from the getMessageList operation.
         * 
         * The following main steps are done: - Create the parameters of the new message - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */
    
        [Test]
        public void testGetFullMessageDifferentMimeTypes() {
            /*
             * Create the parameters of the new message
             */
            try {
    
                Addressee addresseeForBoxIdType = EhboxTestUtilities.mapBoxIdTypeToAddressee(mailBoxToUse);
                DocumentMessage fullExampleMessage = EhboxTestDataBuilder.buildFullExampleDocumentMessage(true, true, addresseeForBoxIdType);
                fullExampleMessage.getAnnexList().add(EhboxTestDataBuilder.generateDocument("DocWithmimeType text xml", "text/xml"));
                fullExampleMessage.getAnnexList().add(EhboxTestDataBuilder.generateDocument("DocWithmimeType application/octet-stream", "application/octet-stream"));
                fullExampleMessage.getAnnexList().add(EhboxTestDataBuilder.generateDocument("DocWithmimeType application/pdf", "application/pdf"));
                fullExampleMessage.getAnnexList().add(EhboxTestDataBuilder.generateDocument("DocWithmimeType text plain", "text/plain"));
                fullExampleMessage.getAnnexList().add(EhboxTestDataBuilder.generateDocument("DocWithmimeType unknown", "unknown"));
                fullExampleMessage.getDocument().setTitle("ConnectorTest : testMessageWithAnnexesInDifferentMimeTypes:boxId=" + mailBoxToUse);
                SendMessageResponse sendMessageResponse = ServiceFactory.getEhealthBoxServiceV3().sendMessage(BuilderFactory.getSendMessageBuilder().buildMessage(fullExampleMessage));
                string multipartMessageId = sendMessageResponse.getId();
    
    
                /*
                 * Invoke the business connector framework's eHealthBox's getFullMessage operation
                 */
    
                GetFullMessageRequest request = new GetFullMessageRequest();
    
                GetMessagesListRequest listRequest = new GetMessagesListRequest();
                listRequest.setSource("INBOX");
                GetMessageListResponseType listResponse = ServiceFactory.getEhealthBoxServiceV3().getMessageList(listRequest);
                java.util.List messages = listResponse.getMessages();
    
                Assert.IsFalse(messages.isEmpty(),"no messages found");
                request.setSource("INBOX");
    
                request.setMessageId(multipartMessageId);
    
                EhboxTestUtilities.waitForProcessing();
                GetFullMessageResponse response = ServiceFactory.getEhealthBoxServiceV3().getFullMessage(request);
    
                /*
                 * Verify the response
                 */
    
                // check if the message has been returned
                Assert.IsNotNull(response.getMessage().getPublicationId());
                be.ehealth.businessconnector.ehbox.api.domain.Message msg = BuilderFactory.getConsultationMessageBuilder().buildFullMessage(response);
                if (msg.GetType() == typeof(DocumentMessage)) {
                    DocumentMessage message = (DocumentMessage) msg;
                } else if (msg.GetType() == typeof(NewsMessage)) {
                    NewsMessage message = (NewsMessage) msg;
                    Assert.IsNotNull(message);
                }
            } catch (java.lang.Exception e) {
                EhboxTestUtilities.logStackTrace(e);
                Assert.Fail(e.getMessage());
            }
        }
        
        /**
         * 
         */
        private string getMessageId(java.util.List list) {
            Iterator itr = list.iterator();
            while (itr.hasNext()) {
                consultation.Message message = (consultation.Message) itr.next();
                if ("DOCUMENT".Equals(message.getContentSpecification().getContentType()) || "NEWS".Equals(message.getContentSpecification().getContentType())) {
                    return message.getMessageId();
                }
            }
            Assert.Fail("no publication founded, try again");
            return null;
        }

        /**
         * Test the getHistory operation from the eHealthBox Service through the use of the Business Connector. This test retrieves the history
         * based on a given messageId. the list that is returned is a list of Strings containing messageId's.
         * 
         * The following main steps are done: - Create the parameters of the new message - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */
        [Test]
        public void testGetHistory(){
    
            string expectedOldMessageId = null;
            /*
             * Create the parameters of the new message
             */
            MessageRequestType request = new MessageRequestType();
            // set the messageId, use the messageId of the message that has been sent in testSendMessage
            request.setMessageId(getCreatedNewsIdForMailbox(mailBoxToUse));
            expectedOldMessageId = getCreatedOldNewsIdForMailbox(mailBoxToUse);
            request.setSource("INBOX");
    
            /*
             * Invoke the business connector framework's eHealthBox's getFullMessage operation
             */
            GetHistoryResponse response = ServiceFactory.getEhealthBoxServiceV3().getMessageHistory(request);
    
            Assert.AreEqual(1, response.getMessageIds().size());
            Assert.AreEqual(expectedOldMessageId, response.getMessageIds().get(0));
    
            /*
             * Verify the response
             */
            // check if there are no errors
            Assert.AreEqual("100", response.getStatus().getCode());
            // check if the message has been returned
            Assert.IsNotNull(response.getMessageIds());
        }

        [Test]
        public void testGetAllMessagesForAllEhboxes() {
            string source = "SENTBOX";
            java.util.List retrievedListOfIds = retrieveAllMessageIdsForAllEHboxesForSource(source);
    
            java.util.List allMessageIds= getAllCreatedMessageIds();
            for (int i = 0; i < allMessageIds.size(); i++) {
                string expectedMessageId = (string) allMessageIds.get(i);
                bool doesListContainMessage = retrievedListOfIds.contains(expectedMessageId);
                string errorDescription = "expected messageId  " + expectedMessageId + "not found in list " + StringUtils.join(retrievedListOfIds.iterator(), ", ");
                
                Assert.IsTrue(doesListContainMessage);
            }
        }
    
        /**
         * @param source
         * @return
         * @throws ConnectorException
         * @throws TechnicalConnectorException
         */
        public java.util.List retrieveAllMessageIdsForAllEHboxesForSource(string source) {
            java.util.List fullListOfIds = new ArrayList();
            int cursor = 1;
            int increment = 99;
            GetMessageListResponseType allEhboxesMessagesList = ServiceFactory.getEhealthBoxServiceV3().getAllEhboxesMessagesList(BuilderFactory.getRequestBuilder().createAllEhboxesMessagesListRequest(source,new java.lang.Integer(cursor), new java.lang.Integer(cursor + increment)));
            java.util.List retrievedListOfIds = getListOfMessageIdsFromResponse(allEhboxesMessagesList);
            fullListOfIds.addAll(retrievedListOfIds);
            while (retrievedListOfIds.size() > increment) {
                cursor = cursor + increment;
                allEhboxesMessagesList = ServiceFactory.getEhealthBoxServiceV3().getAllEhboxesMessagesList(BuilderFactory.getRequestBuilder().createAllEhboxesMessagesListRequest(source, new java.lang.Integer(cursor), new java.lang.Integer(cursor + increment)));
                retrievedListOfIds = getListOfMessageIdsFromResponse(allEhboxesMessagesList);
                fullListOfIds.addAll(retrievedListOfIds);
            }
            logList("ALL MAILBOXES for source " + source, fullListOfIds);
            return fullListOfIds;
        }
        
        /**
         * Test the moveToInbox operation from the eHealthBox Service through the use of the Business Connector. This moves a message from the
         * BIN folder to the INBOX folder based on a given messageId.
         * 
         * The following main steps are done: - Create the parameters of the new message - Invoke the business connector - Verify the response
         * 
         * @throws Exception
         */
        [Test]
        public void testMoveToInbox(){
            try {

                string messageIdToUse = null;
                java.util.List originalMessagesInInbox = getListOfMessagesForSource("SENTBOX", mailBoxToUse);
                Assert.False(originalMessagesInInbox.isEmpty());
                java.util.List originalMessagesInBinInbox = getListOfMessagesForSource("BINSENTBOX", mailBoxToUse);

                // ServiceFactory.getEhealthBoxServiceV3().

                messageIdToUse = getCreatedDocumentIdForMailbox(mailBoxToUse);


                Assert.True(originalMessagesInInbox.contains(messageIdToUse), "message " + messageIdToUse + " not found in originallistOfMessages");
                Assert.False(originalMessagesInBinInbox.contains(messageIdToUse), "message " + messageIdToUse + " found in new listOfMessages after move , should have moved");

                /*
                 * Invoke the business connector framework's eHealthBox's getFullMessage operation
                 */
                ResponseType response = ServiceFactory.getEhealthBoxServiceV3().moveMessage(BuilderFactory.getRequestBuilder().createMoveMessageRequest("SENTBOX", "BINSENTBOX", mailBoxToUse, messageIdToUse));

                java.util.List newMessagesInInbox = getListOfMessagesForSource("SENTBOX", mailBoxToUse);
                java.util.List newMessagesInBinInbox = getListOfMessagesForSource("BINSENTBOX", mailBoxToUse);
                Assert.False(newMessagesInBinInbox.isEmpty());


                Assert.True(newMessagesInBinInbox.contains(messageIdToUse), "message " + messageIdToUse + " not found in new location after move ");
                Assert.False(newMessagesInInbox.contains(messageIdToUse), "message " + messageIdToUse + "  found in old location after move");

                // restore previous state :
                ServiceFactory.getEhealthBoxServiceV3().moveMessage(BuilderFactory.getRequestBuilder().createMoveMessageRequest("BINSENTBOX", "SENTBOX", mailBoxToUse, messageIdToUse));

                /*
                 * Verify the response
                 */
                // check if there are no errors
                Assert.AreEqual("100", response.getStatus().getCode());
            } catch (java.lang.Exception e) {
                EhboxTestUtilities.logStackTrace(e);
                Assert.Fail(e.getMessage());
            }
        }

        [Test]
        public void testGetAcknowledgement() {
            string messageIdToUse = null;
            messageIdToUse = getCreatedDocumentIdForMailbox(mailBoxToUse);
            GetMessageAcknowledgmentsStatusResponse messageAcknowledgmentsStatusResponse = ServiceFactory.getEhealthBoxServiceV3().getMessageAcknowledgmentsStatusRequest(BuilderFactory.getRequestBuilder().createGetMessageAcknowledgmentsStatusRequest(messageIdToUse, new java.lang.Integer(1), new java.lang.Integer(100), mailBoxToUse));
            AcknowledgmentsStatus acknowledgmentsStatus = messageAcknowledgmentsStatusResponse.getAcknowledgmentsStatus();
            Assert.IsFalse(acknowledgmentsStatus.getRows().isEmpty());
            StringBuilder sb = new StringBuilder("messageAcknowledgmentStatus : ");
            
            java.util.List rows = acknowledgmentsStatus.getRows();
            for (int i = 0; i < rows.size(); i++) {
                be.fgov.ehealth.ehbox.consultation.protocol.v3.Row status = (be.fgov.ehealth.ehbox.consultation.protocol.v3.Row)acknowledgmentsStatus.getRows().get(i);
                sb.append("\n receiver :").append(status.getRecipient().getId()).append(status.getRecipient().getType());
                sb.append(" readTime :").append(status.getRead());
                sb.append(", published :").append(status.getPublished());
                sb.append(" received : ").append(status.getReceived());
                if (EhboxTestDataBuilder.getInssUser1().Equals(status.getRecipient().getId())) {
                    Assert.IsNotNull(status.getReceived());
                }
            }
            Assert.AreEqual("100", messageAcknowledgmentsStatusResponse.getStatus().getCode());
        }
    
        [Test]
        public void testProblemGetAllMessages() {
            java.util.List list = EhboxTestUtilities.getListOfAllSources();
            for (int i = 0 ; i < list.size(); i++) {
                string source = (string) list.get(i);
                java.util.List listOfMessagesForSource = getListOfMessagesForSource(source, mailBoxToUse);
                java.util.List retrieveAllMessageIdsForAllEHboxesForSourceList = retrieveAllMessageIdsForAllEHboxesForSource(source);
                
                for (int j = 0; j < listOfMessagesForSource.size(); j++) {
                    string messageId = (string)listOfMessagesForSource.get(j);
                    Assert.IsTrue(retrieveAllMessageIdsForAllEHboxesForSourceList.contains(messageId));
                }
            }
    
        }
    }
}
