package be.ehealth.businessconnector.ehbox.v3.session;

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

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runners.MethodSorters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.businessconnector.ehbox.api.domain.Addressee;
import be.ehealth.businessconnector.ehbox.api.domain.NewsMessage;
import be.ehealth.businessconnector.ehbox.api.utils.QualityType;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestUtilities;
import be.ehealth.businessconnector.ehbox.v3.builders.BuilderFactory;
import be.ehealth.businessconnector.ehbox.v3.builders.RequestBuilder;
import be.ehealth.businessconnector.ehbox.v3.builders.SendMessageBuilder;
import be.ehealth.technicalconnector.utils.IdentifierType;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetFullMessageRequest;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetFullMessageResponse;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetHistoryRequest;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetHistoryResponse;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetMessageListResponseType;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.Message;
import be.fgov.ehealth.ehbox.publication.protocol.v3.SendMessageRequest;
import be.fgov.ehealth.ehbox.publication.protocol.v3.SendMessageResponse;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.RestoreSystemProperties;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;

/**
 * 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.
 * 
 * @author EHP
 * 
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class NewsIntegrationTest {

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

    private static final String NEWS1TITLE = "News 1  " + new Date();

    private static final String NEWS2TITLE = "News 2  " + new Date();

    private static SendMessageBuilder messageBuilder;

    private static RequestBuilder requestBuilder;

    private static EhealthBoxServiceV3 service;

    private static String message1Id;


    private static String message2Id;

    @ClassRule
    public static RuleChain chain = RuleChain.outerRule(new RestoreSystemProperties()).around(SessionRule.withActiveSession().forEnvironment("acc").forProfession("persphysician").forUser("hannes").build());

    @BeforeClass
    public static void initSession() throws Exception {
        messageBuilder = BuilderFactory.getSendMessageBuilder();
        requestBuilder = BuilderFactory.getRequestBuilder();
        service = ServiceFactory.getEhealthBoxServiceV3();
    }

    @Test
    public void _00_publishNews() throws Exception {
        NewsMessage<Message> news = new NewsMessage<Message>();
        news.getDocument().setTitle(NEWS1TITLE);
        news.getDocument().setContent("eureka".getBytes());
        news.getDocument().setFilename("test.txt");

        news.setDestinations(getDestination());
        news.setImportant(true);
        news.setEncrypted(false);

        SendMessageRequest requestPublication1 = messageBuilder.buildMessage(news);
        SendMessageResponse responsePublication1 = service.sendMessage(requestPublication1);

        Assert.assertEquals("100", responsePublication1.getStatus().getCode());
        Assert.assertNotNull(responsePublication1.getId());

        LOG.debug("TESTLOG : Publication id of the message1 (Id =" + responsePublication1.getId() + ") : " + responsePublication1.getSentPublicationId());
        message1Id = responsePublication1.getId();

        NewsMessage<Message> news2 = new NewsMessage<Message>();
        news2.getDocument().setTitle(NEWS2TITLE);
        news2.getDocument().setContent("eureka".getBytes());
        news2.getDocument().setFilename("test.txt");

        news2.setDestinations(getDestination());
        news2.setImportant(true);
        news2.setEncrypted(false);

        SendMessageRequest requestPublication2 = messageBuilder.buildMessage(news2);
        requestPublication2.setPublicationId(responsePublication1.getSentPublicationId());

        SendMessageResponse responsePublication2 = service.sendMessage(requestPublication2);

        Assert.assertEquals("100", responsePublication2.getStatus().getCode());
        Assert.assertNotNull(responsePublication2.getId());

        LOG.debug("TESTLOG : Publication id of the message2 (Id =" + responsePublication2.getId() + ") : " + responsePublication2.getSentPublicationId());
        Assert.assertEquals("Publication id not the same fort the two messages", responsePublication1.getSentPublicationId(), responsePublication2.getSentPublicationId());
        
        EhboxTestUtilities.waitForProcessing();
    }

    @Test
    public void _01_getLatestNewsId() throws Exception {
        String source = "INBOX";
        GetMessageListResponseType responseGetList = service.getMessageList(requestBuilder.createGetMessagesListRequest(source));

        Assert.assertEquals("100", responseGetList.getStatus().getCode());
        Assert.assertNotNull("No messages found in the box", responseGetList.getMessages());

        for (Message message : responseGetList.getMessages()) {
            if (NEWS2TITLE.equals(message.getContentInfo().getTitle())) {
                message2Id = message.getMessageId();
            }
        }

        Assert.assertNotNull("Latest message not found", message2Id);
        LOG.debug("TESTLOG : Latest message found with id : " + message2Id);
    }

    @Test
    public void _02_getHistory() throws Exception {
        GetHistoryRequest requestHistory = new GetHistoryRequest();
        requestHistory.setMessageId(message2Id);
        requestHistory.setSource("INBOX");

        GetHistoryResponse responseHistory = service.getMessageHistory(requestHistory);

        Assert.assertEquals("100", responseHistory.getStatus().getCode());
        Assert.assertNotNull(responseHistory.getMessageIds());
        Assert.assertEquals(1, responseHistory.getMessageIds().size());

        LOG.debug("TESTLOG : History message found with id : " + responseHistory.getMessageIds().get(0));
        Assert.assertEquals("Message1 id not found in history", message1Id, responseHistory.getMessageIds().get(0));
    }

    @Test
    public void _04_consultHistoryMessage() throws Exception {
        GetFullMessageRequest requestFullMessage = new GetFullMessageRequest();
        requestFullMessage.setSource("HISTORY");
        requestFullMessage.setMessageId(message1Id);

        GetFullMessageResponse responseFullMessage = service.getFullMessage(requestFullMessage);

        String titleOfMessage = responseFullMessage.getMessage().getContentContext().getContent().getDocument().getTitle();
        LOG.debug("TESTLOG : Title of the full message : " + titleOfMessage);
        Assert.assertEquals("Title of the news received is incorrect", NEWS1TITLE, titleOfMessage);
    }

    private List<Addressee> getDestination() {
        List<Addressee> addresseeList = new ArrayList<Addressee>();
        Addressee addressee = new Addressee(IdentifierType.NIHII);
        addressee.setId("18334780004");
        addressee.setQuality(QualityType.DOCTOR_NIHII);
        addresseeList.add(addressee);

        return addresseeList;
    }

}
