#region Header

/*
 * Copyright (c) eHealth
 */

#endregion Header

/**
 * Codage Service Integration Tests
 * This set of tests shows the use of the Codage Service through the use of the Technical Connector
 */
namespace be.ehealth.technicalconnector.service.seals
{
    using System;

    using be.ehealth.technicalconnector.config;
    using be.ehealth.technicalconnector.exception;
    using be.ehealth.technicalconnector.service;
    using be.ehealth.technicalconnector.service.sts.security;
    using be.ehealth.technicalconnector.service.sts.security.impl;
    using be.ehealth.technicalconnector.utils;
    using be.ehealth.technicalconnector.utils.net;
    using be.fgov.ehealth.seals.core.v1;
    using be.fgov.ehealth.seals.protocol.v1;

    using java.util;

    using NUnit.Framework;

    [TestFixture]
    public class SealsServiceIntegrationTest
    {
        #region Fields

        private static KeyStoreCredential credential;

        /** The decoded text, used in encode (input), checked in decode (verify against returned decoded text) */
        private String plainText = "Private text to be encoded";

        #endregion Fields

        #region Methods

        [SetUpAttribute]
        public static void init()
        {
            /*
             * Invoke the technical connector framework's Codage Service's encode operation
             */
            // get the X509 certificate and private key from the test keystore. (retrieved from property file)
            credential = new KeyStoreCredential(
                TestPropertiesLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net").getProperty("test.seals.location"),
                TestPropertiesLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net").getProperty("test.seals.alias"),
                TestPropertiesLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net").getProperty("test.seals.password"));
        }

        public byte[] invokeEncode()
        {
            /*
             * Set the values to use in this test
             */
            // the application name (retrieved from property file)
            String applicationName = TestPropertiesLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net").getProperty("test.applicationname");
            // the message ID (1 per message)
            String id = "_1";
            // the message to encode (stored in class variable for use with the decode)
            String message = plainText;
            // randomize the returned values?
            String algorithmCode ="F";

            /*
             * Create request
             */
            // create encode request
            EncodeRequest request = new EncodeRequest();
            // set application name
            request.setApplicationName(applicationName);
            // the request expects a list of original data to be encoded.
            // in this example we will provide a list with 1 item to be encoded
            java.util.List listOriginalData = new ArrayList();
            // create the item to be encoded
            OriginalDataType originalData = new OriginalDataType();
            // set id
            originalData.setId(id);
            // set the actual text to be encoded
            originalData.setInputData(message);
            // set if the data has to be randomized or not
            originalData.setAlgorithmCode(algorithmCode);
            // add the data to the list of data to be encoded
            listOriginalData.add(originalData);
            // add the list of data to the encode request
            request.getOriginalDatas().addAll(listOriginalData);

            // invoke technical connector
            SealsService service = ServiceFactory.getSealsService();
            EncodeResponse response = service.encode(credential.getCertificate(), credential.getPrivateKey(), request);

            /*
             * Verify the response
             */
            // check if a ticket number is present
            Assert.IsNotNull(response.getId());
            // as the request expects a list of data to be encoded, the response gives a list of encoded data as result
            // the example requests the encoding of 1 entry in the list, so we just get the first response out.
            ChoiceEncodedDataErrorType encodedData = ((ChoiceEncodedDataErrorType)response.getResponses().get(0));
            // check if the ID is the same as the one that has been entered in the request
            Assert.AreEqual(id, encodedData.getEncodedData().getId());
            // check if the data has been encoded
            Assert.IsNotNull(encodedData.getEncodedData().getValue());
            // check if there is no error present
            Assert.IsNull(encodedData.getError());

            // save the encoded data in the variable for use with the decode test
            return encodedData.getEncodedData().getValue();
        }

        /**
         * Test the decode operation of the Codage Service through the use of the Technical Connector
         *
         * The decode methods needs the following parameters:
         * - application name
         * - ID(s) of the message(s) to decode
         * - message(s) to decode
         * - randomize? (boolean)
         *
         * @throws TechnicalConnectorException
         *             the technical connector exception
         */
        [Test]
        public void testDecode()
        {
            /*
             * Set the values to use in this test
             */
            // the application name (retrieved from property file)
            String applicationName = TestPropertiesLoader.getProperties("be.ehealth.technicalconnector.test.properties",".net").getProperty("test.applicationname");
            // the message ID (1 per message)
            String id = "_1";

            byte[] encodedText = invokeEncode();

            /*
             * Create request
             */
            // create decode request
            DecodeRequest requestDecode = new DecodeRequest();
            // set application name
            requestDecode.setApplicationName(applicationName);
            // the request expects a list of encoded data to be decoded.
            // in this example we will provide a list with 1 item to be decoded
            java.util.List listEncodedData = new java.util.ArrayList();
            // create the item to be decoded
            EncodedDataType encodedDataDecode = new EncodedDataType();
            // set id
            encodedDataDecode.setId(id);
            // set the encoded text to be decoded
            encodedDataDecode.setValue(encodedText);
            // add the encoded data to the list of data to be decoded
            listEncodedData.add(encodedDataDecode);
            // add the list of data to the decode request
            requestDecode.getEncodedDatas().addAll(listEncodedData);

            // invoke technical connector
            SealsService serviceDecode = ServiceFactory.getSealsService();
            DecodeResponse responseDecode = serviceDecode.decode(credential.getCertificate(), credential.getPrivateKey(), requestDecode);

            /*
             * Verify the response
             */
            // check if a ticket number is present
            Assert.IsNotNull(responseDecode.getId());
            // as the request expects a list of data to be decoded, the response gives a list of decoded data back
            // the example requests the decoding of 1 entry in the list, so we just get the first response out.
            ChoiceDecodedDataErrorType decodedData = (ChoiceDecodedDataErrorType) responseDecode.getResponses().get(0);
            // check if the ID is the same as the one that has been entered in the request
            Assert.AreEqual(id, decodedData.getDecodedData().getId());
            // check if the data has been decoded correct
            Assert.AreEqual(plainText, decodedData.getDecodedData().getOutputData());
            // check if there is no error present
            Assert.IsNull(decodedData.getError());
        }

        /**
         * Test the encode operation of the Codage Service through the use of the Technical Connector
         *
         * The encode methods needs the following parameters:
         * - application name
         * - ID(s) of the message(s) to encode
         * - message(s) to encode
         * - randomize? (boolean)
         *
         * @throws TechnicalConnectorException
         *             the technical connector exception
         */
        [Test]
        public void testEncode()
        {
            invokeEncode();
        }

        #endregion Methods
    }
}