/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.hub.session;

import java.util.List;

import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import be.ehealth.business.kmehrcommons.helper.ErrorTypeManagement;
import be.ehealth.businessconnector.hub.exception.IntraHubBusinessConnectorException;
import be.ehealth.technicalconnector.exception.ConnectorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.fgov.ehealth.hubservices.core.v1.ConsentType;
import be.fgov.ehealth.hubservices.core.v1.GetTransactionListResponse;
import be.fgov.ehealth.hubservices.core.v1.GetTransactionResponse;
import be.fgov.ehealth.hubservices.core.v1.LocalSearchType;
import be.fgov.ehealth.hubservices.core.v1.PatientIdType;
import be.fgov.ehealth.hubservices.core.v1.PutTransactionResponse;
import be.fgov.ehealth.hubservices.core.v1.RevokeTransactionResponse;
import be.fgov.ehealth.hubservices.core.v1.TherapeuticLinkType;
import be.fgov.ehealth.hubservices.core.v1.TransactionBaseType;
import be.fgov.ehealth.hubservices.core.v1.TransactionIdType;
import be.fgov.ehealth.hubservices.core.v1.TransactionWithPeriodType;
import be.fgov.ehealth.standards.kmehr.schema.v1.ErrorType;
import be.fgov.ehealth.standards.kmehr.schema.v1.FolderType;
import be.fgov.ehealth.standards.kmehr.schema.v1.Kmehrmessage;


/**
 * Transactions operations Test
 * 
 * @author EH054
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TransactionIntegrationTest extends AbstractIntrahubIntegrationTest {

    private static ConsentType consent;

    private static TherapeuticLinkType therapeuticLink;

    @BeforeClass
    public static void initConsent() throws ConnectorException {
        consent = HubTestHelper.createConsentType();
        therapeuticLink = HubTestHelper.createTherapeuticLinkType();

        hubServiceComplete.putPatientConsent(consent);
        hubServiceComplete.putTherapeuticLink(therapeuticLink);
    }

    @AfterClass
    public static void teardownConsent() throws TechnicalConnectorException, IntraHubBusinessConnectorException {
        therapeuticLink.setEnddate(new DateTime());
        hubServiceComplete.revokeTherapeuticLink(therapeuticLink);

        consent.setRevokedate(new DateTime());
        hubServiceComplete.revokePatientConsent(consent);
    }

    /**
     * PutTransaction Test
     */
    @Test
    public void testAputTransaction() throws Exception {
        PutTransactionResponse putTransaction = hubServiceComplete.putTransaction(createTransactionForPut());

        hubServiceComplete.revokeTransaction(HubTestHelper.createPatientIdType(), createTransactionId());

        List<ErrorType> errors = putTransaction.getAcknowledge().getErrors();
        Assert.assertTrue(ErrorTypeManagement.printErrors(errors), errors.isEmpty());
    }

    /**
     * GetTransaction Test
     */
    @Test
    public void testBgetTransaction() throws Exception {
        hubServiceComplete.putTransaction(createTransactionForPut());

        PatientIdType patientId = HubTestHelper.createPatientIdType();
        GetTransactionResponse transactionResponse = hubServiceComplete.getTransaction(patientId, createTransactionBaseType());
        hubServiceComplete.revokeTransaction(patientId, createTransactionId());

        List<ErrorType> errors = transactionResponse.getAcknowledge().getErrors();
        Assert.assertTrue(ErrorTypeManagement.printErrors(errors), errors.isEmpty());
    }

    /**
     * GetTransactionList Test
     */
    @Test
    public void testCgetTransactionList() throws Exception {
        hubServiceComplete.putTransaction(createTransactionForPut());

        PatientIdType patientId = HubTestHelper.createPatientIdType();
        GetTransactionListResponse transactionList = hubServiceComplete.getTransactionList(patientId, LocalSearchType.LOCAL, createTransactionWithPeriodType());
        hubServiceComplete.revokeTransaction(patientId, createTransactionId());

        List<ErrorType> errors = transactionList.getAcknowledge().getErrors();
        Assert.assertTrue(ErrorTypeManagement.printErrors(errors), errors.isEmpty());
    }

    @Test
    public void testDrevokeTransaction() throws Exception {
        hubServiceComplete.putTransaction(createTransactionForPut());

        RevokeTransactionResponse revokeTransaction = hubServiceComplete.revokeTransaction(HubTestHelper.createPatientIdType(), createTransactionId());

        List<ErrorType> errors = revokeTransaction.getAcknowledge().getErrors();
        Assert.assertTrue(ErrorTypeManagement.printErrors(errors), errors.isEmpty());
    }

    /*
     * Methods used by the tests
     */

    /**
     * Create a transactionWithPeriod type for transaction operations
     */
    private TransactionWithPeriodType createTransactionWithPeriodType() {
        TransactionWithPeriodType transaction = new TransactionWithPeriodType();
        transaction.setAuthor(HubTestHelper.createAuthor());
        transaction.setBegindate(new DateTime());
        transaction.setEnddate(new DateTime());
        return transaction;
    }

    /**
     * Create a transaction base type for transaction operations
     */
    private TransactionBaseType createTransactionBaseType() throws Exception {
        TransactionBaseType transaction = new TransactionBaseType();
        transaction.setAuthor(HubTestHelper.createAuthor());
        transaction.setId(HubTestHelper.createTransactionId(transactionId));
        return transaction;
    }

    private Kmehrmessage createTransactionForPut() throws Exception {
        Kmehrmessage transaction = new Kmehrmessage();
        transaction.setHeader(HubTestHelper.createHeader());

        FolderType folder = new FolderType();
        folder.getIds().add(HubTestHelper.createMessageId(HubConfig.MESSAGE_ID));
        folder.setPatient(HubTestHelper.createPatientForTransaction());
        folder.getTransactions().add(HubTestHelper.createTransactionType());
        transaction.getFolders().add(folder);
        return transaction;
    }

    private TransactionIdType createTransactionId() {
        TransactionIdType transid = new TransactionIdType();
        transid.getIds().add(HubTestHelper.createTransactionId(transactionId));
        return transid;
    }

}
