/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.ehbox.v3.testcases;

import org.hamcrest.CoreMatchers;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import be.ehealth.businessconnector.ehbox.api.domain.Addressee;
import be.ehealth.businessconnector.ehbox.api.domain.DocumentMessage;
import be.ehealth.businessconnector.ehbox.api.utils.QualityType;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestDataBuilder;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestUtilities;
import be.ehealth.businessconnector.ehbox.v3.MessageBuilder;
import be.ehealth.businessconnector.ehbox.v3.builders.BuilderFactory;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.utils.IdentifierType;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetBoxInfoResponse;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetFullMessageResponse;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetMessageAcknowledgmentsStatusResponse;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.Message;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.Row;
import be.fgov.ehealth.ehbox.core.v3.BoxIdType;
import be.fgov.ehealth.ehbox.publication.protocol.v3.SendMessageRequest;
import be.fgov.ehealth.ehbox.publication.protocol.v3.SendMessageResponse;


/**
 * @author eh062
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SendingUnencryptedMessageToInstitutionIntegrationTest {

    private static final String MESSAGE_TITLE = "Scenario 1";

    private static final String MESSAGE_CONTENT = "message test connector scenario 1";

    private static final String MESSAGE_DESTINATION_ID = "0809394427";

    private static final String MESSAGE_DESTINATION_ID_TYPE = "CBE";

    private static final String MESSAGE_DESTINATION_QUALITY = "INSTITUTION";

    private static final String EXPECTED_RESPONSE_CODE = "100";

    private static final String INBOX = "INBOX";

    private static final String SENTBOX = "SENTBOX";

    private static final BoxIdType BOX_ID = EhboxTestDataBuilder.generateBoxId(MESSAGE_DESTINATION_ID, MESSAGE_DESTINATION_ID_TYPE, MESSAGE_DESTINATION_QUALITY);

    private static String currentMessageId;

    /*************************************/
    /*                                   */
    /* JUNIT METHODS */
    /*                                   */
    /*************************************/


    @BeforeClass
    public static void checkSenderIsDoctor() throws TechnicalConnectorException {
        Assume.assumeTrue(EhboxTestUtilities.isDoctorTest());
    }

    @BeforeClass
    public static void setUp() throws Exception {
        EhboxTestUtilities.createSession();
    }

    @AfterClass
    public static void tearDown() {
        EhboxTestUtilities.destroySession();
    }

    /*************************************/
    /*                                   */
    /* TEST METHODS */
    /*                                   */
    /*************************************/

    private SendMessageRequest prepareAndVerifySendMessageRequest(DocumentMessage<Message> message) throws Exception {
        SendMessageRequest request = EhboxTestUtilities.prepareSendRequest(message);

        Assert.assertFalse("There should not be a receipt on the publication set", request.getContentContext().getContentSpecification().isPublicationReceipt());
        Assert.assertFalse("There should not be a receipt on the read set", request.getContentContext().getContentSpecification().isReadReceipt());
        Assert.assertFalse("There should not be a receipt on the reception set", request.getContentContext().getContentSpecification().isReceivedReceipt());

        return request;
    }

    @Test
    public void testStep1sendUnecryptedMessageFromDoctorToInstitution() throws Exception {
        final Addressee destination = EhboxTestDataBuilder.generateDestination(MESSAGE_DESTINATION_ID, IdentifierType.CBE, QualityType.INSTITUTION_CBE);
        MessageBuilder builder = MessageBuilder.create(destination, MESSAGE_CONTENT).title(MESSAGE_TITLE);
        SendMessageRequest request = this.prepareAndVerifySendMessageRequest(EhboxTestDataBuilder.generateDocumentMessage(builder));

        SendMessageResponse response = EhboxTestUtilities.sendMessage(request);

        Assert.assertEquals(EXPECTED_RESPONSE_CODE, response.getStatus().getCode());

        currentMessageId = response.getId();
        Assert.assertNotNull("Message ID should not be null", currentMessageId);

        EhboxTestUtilities.waitForProcessing();
    }

    @Test
    public void testStep2checkIfMessageIsInList() throws Exception {
        Assert.assertTrue("The message with id " + currentMessageId + " should be in the list", EhboxTestUtilities.isMessageInList(currentMessageId, INBOX, BOX_ID));
    }

    @Test
    public void testStep3verifyAcknowledgments() throws Exception {
        GetMessageAcknowledgmentsStatusResponse acks = EhboxTestUtilities.getMessageAcknowledgements(currentMessageId, EhboxTestDataBuilder.getEhboxSender());

        for (Row currentAcknowledgementsStatus : acks.getAcknowledgmentsStatus().getRows()) {
            Assert.assertNull("The message should not have been read yet", currentAcknowledgementsStatus.getRead());
            Assert.assertNotNull("The message should have been received", currentAcknowledgementsStatus.getReceived());
        }
    }

    @Test
    public void testStep4verifyFullMessage() throws Exception {
        GetFullMessageResponse fullMessage = EhboxTestUtilities.getFullMessage(currentMessageId, INBOX, BOX_ID);

        be.ehealth.businessconnector.ehbox.api.domain.Message<GetFullMessageResponse> retrievedFullMessage = BuilderFactory.getConsultationMessageBuilder().buildFullMessage(fullMessage);
        Assert.assertThat("The message " + currentMessageId + " should be of type DocumentMessage", retrievedFullMessage, CoreMatchers.instanceOf(DocumentMessage.class));

        DocumentMessage<GetFullMessageResponse> inboxMessage = (DocumentMessage<GetFullMessageResponse>) retrievedFullMessage;

        String messageTitle = inboxMessage.getDocumentTitle();
        Assert.assertTrue("Message title should be \"" + MESSAGE_TITLE + "\" but was \"" + messageTitle + "\"", messageTitle.equals(MESSAGE_TITLE));
        Assert.assertTrue("The content of the inbox message is not the expected one", org.bouncycastle.util.Arrays.areEqual(inboxMessage.getDocument().getContent(), MESSAGE_CONTENT.getBytes()));
        Assert.assertFalse("The message should not be encrypted", inboxMessage.isEncrypted());
        Assert.assertFalse("The message should not be important", inboxMessage.isImportant());
        Assert.assertFalse("The message should not have any annex", inboxMessage.isHasAnnex());
        Assert.assertFalse("The message should not have any publication acknowledgment", inboxMessage.isUsePublicationReceipt());
        Assert.assertFalse("The message should not have any read acknowledgment", inboxMessage.isUseReadReceipt());
        Assert.assertFalse("The message should not have any reception acknowledgment", inboxMessage.isUseReceivedReceipt());
        Assert.assertFalse("The message should not have any free information", inboxMessage.isHasFreeInformations());
        Assert.assertTrue("The message should not have any custom metadata", inboxMessage.getCustomMetas().size() == 0);
    }

    @Test
    public void testStep5verifyBoxInfo() throws Exception {
        GetBoxInfoResponse boxInfo = EhboxTestUtilities.getBoxInfo(BOX_ID);
        Assert.assertTrue("There should not be any message in standby", boxInfo.getNbrMessagesInStandBy() == 0);
        Assert.assertTrue("BoxId should be " + BOX_ID.getId() + " but was " + boxInfo.getBoxId().getId(), BOX_ID.getId().equals(boxInfo.getBoxId().getId()));
        Assert.assertTrue("BoxId should be " + BOX_ID.getType() + " but was " + boxInfo.getBoxId().getType(), BOX_ID.getType().equals(boxInfo.getBoxId().getType()));
        Assert.assertTrue("BoxId should be " + BOX_ID.getQuality() + " but was " + boxInfo.getBoxId().getQuality(), BOX_ID.getQuality().equals(boxInfo.getBoxId().getQuality()));
    }

    @Test
    public void testStep6deleteMessage() throws Exception {
        EhboxTestUtilities.deleteMessages(INBOX, BOX_ID, currentMessageId);
        EhboxTestUtilities.deleteMessages(SENTBOX, EhboxTestDataBuilder.getEhboxSender(), currentMessageId);
    }

}
