package be.ehealth.technicalconnector.service.timestamp;

import java.io.IOException;
import java.util.Properties;

import org.bouncycastle.tsp.TimeStampToken;
import org.joda.time.DateTime;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.behealth.webservices.tsa.PeriodType;
import be.behealth.webservices.tsa.TSConsultRequest;
import be.behealth.webservices.tsa.TSConsultTSBagRequest;
import be.behealth.webservices.tsa.TimeStampIdentification;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.ehealth.technicalconnector.utils.MarshallerHelper;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;

/**
 * Time Stamping Service Integration Tests This test shows the use of the Time Stamping Consult Service through the use of the Technical
 * Connector.
 * 
 * All Tests require the following pre-requisites to be met: - An eHealth certificate with access to the Time Stamping service
 * 
 * @author EHP
 */
public class TimeStampingConsultationTest {

    private static byte[] tsToken;

    private static Properties config;

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

    /**
     * Test the SignRequest operation from the Time Stamping Authority Service through the use of the Technical Connector. This test creates
     * a time stamp for a given document which can be used later to validate the document.
     * 
     * The following main steps are done: - Create the parameters of the new message - Invoke the technical connector - Verify the response
     * (and safe for later use)
     * 
     * @author EHP
     */
    @BeforeClass
    public static void initConfig() throws Exception {
        config = TestPropertiesLoader.getProperties("/be.ehealth.technicalconnector.test.properties");
        tsToken = ConnectorIOUtils.getBytes(TimeStampingConsultationTest.class.getResourceAsStream("/examples/tstoken.base64"));

    }

    /**
     * Test the GetTimeStamp operation from the Time Stamping Consult Service through the use of the Technical Connector. This test
     * retrieves a time stamp from eHealth that has been created for a given hospital, for a given sequenceNr on a given time
     * 
     * The following main steps are done: - Create the parameters of the new message - Invoke the technical connector - Verify the response
     * 
     * @author EHP
     * @author EHP
     */
    @Test
    public void testGetTimeStamp() throws TechnicalConnectorException, IOException {
        /*
         * Set the values to use in this test
         */
        // The id of the hospital, this is by default "tsa_<HOSPITAL_NIHII>_01"
        String idHospital = "tsa_82051234978_01";
        // get the time on which the time stamp was generated
        TimeStampToken timestampToken = TimestampUtil.getTimestamp(tsToken);
        long time = timestampToken.getTimeStampInfo()
                                  .getGenTime()
                                  .getTime();
        // get the sequence number of the timestamp
        String seqNr = timestampToken.getTimeStampInfo()
                                     .getSerialNumber()
                                     .toString();

        /*
         * Create request
         */
        TSConsultTSBagRequest request = new TSConsultTSBagRequest();
        // set the hospital ID (modified NIHII number)
        request.setIDHospital(idHospital);

        // The Time Stamp Identification: the time of the timestamp and the sequence number
        TimeStampIdentification tsIdent = new TimeStampIdentification();
        // set the time when the timestamping of the document occured
        tsIdent.setDateTime(time);
        // set the sequence number of the timestamp
        tsIdent.setSequenceNumber(seqNr);

        // add the Time Stamp Identification to a list (more than one can be retrieved)
        request.getTSLists()
               .add(tsIdent);


        MarshallerHelper<TSConsultTSBagRequest, TSConsultTSBagRequest> helper = new MarshallerHelper<TSConsultTSBagRequest, TSConsultTSBagRequest>(TSConsultTSBagRequest.class, TSConsultTSBagRequest.class);
        String requestString = helper.toString(request);
        Assert.assertNotNull(requestString);

        LOG.debug(requestString);
    }

    /**
     * Test the CheckCompleteness operation from the Time Stamping Consult Service through the use of the Technical Connector. This test
     * checks if all time stamps that you request are in the eHealth repository.
     * 
     * The following main steps are done: - Create the parameters of the new message - Invoke the technical connector - Verify the response
     * 
     * @author EHP
     * @author EHP
     */
    @Test
    public void testCheckCompleteness() throws TechnicalConnectorException, IOException {
        /*
         * Set the values to use in this test
         */

        String idHospital = config.getProperty("test.timestamping.tsclientid");
        // get the time on which the time stamp was generated
        TimeStampToken timestampToken = TimestampUtil.getTimestamp(tsToken);
        long timestamp = timestampToken.getTimeStampInfo()
                                       .getGenTime()
                                       .getTime();
        // get the sequence number of the timestamp
        String seqNr = timestampToken.getTimeStampInfo()
                                     .getSerialNumber()
                                     .toString();

        // Set the period between which to check the completeness of the timestamps. In this example we will check all timestamps from the
        // past minute

        DateTime startDate = new DateTime(timestamp);
        DateTime endDate = new DateTime(timestamp);
        endDate.plusMinutes(1);

        /*
         * Create request
         */
        TSConsultRequest request = new TSConsultRequest();
        // set the hospital ID (modified NIHII number)
        request.setIDHospital(idHospital);
        // set the period to check
        PeriodType periodType = new PeriodType();
        // set the start date
        periodType.setStart(startDate.getMillis());
        // set the end date
        periodType.setEnd(endDate.getMillis());
        // add the period to the request
        request.setPeriod(periodType);

        // The Time Stamp Identification: the time of the timestamp and the sequence number
        TimeStampIdentification tsIdent = new TimeStampIdentification();
        // set the time when the timestamping of the document occured
        tsIdent.setDateTime(timestamp);
        // set the sequence number of the timestamp
        tsIdent.setSequenceNumber(seqNr);

        // add the Time Stamp Identification to a list (more than one can be retreived
        request.getTSLists()
               .add(tsIdent);


        MarshallerHelper<TSConsultRequest, TSConsultRequest> helper = new MarshallerHelper<TSConsultRequest, TSConsultRequest>(TSConsultRequest.class, TSConsultRequest.class);
        String requestString = helper.toString(request);
        Assert.assertNotNull(requestString);

        LOG.debug(requestString);
    }
}
