/*
 * Copyright (c) eHealth
 */
using System;
using be.ehealth.technicalconnector.session;
using ikvm.extensions;
using NUnit.Framework;
using lang = java.lang;
using java.util;
using joda = org.joda.time;
using be.ehealth.businessconnector.ehbox.api.domain;
using be.ehealth.businessconnector.ehbox.api.domain.exception;
using be.ehealth.businessconnector.ehbox.api.utils;
using be.ehealth.businessconnector.ehbox.v3.builders;
using be.ehealth.businessconnector.ehbox.v3.exception;
using be.ehealth.technicalconnector.exception;
using be.fgov.ehealth.technicalconnector.tests.session;
using be.ehealth.technicalconnector.utils;
using publication = be.fgov.ehealth.ehbox.publication.protocol.v3;
using be.fgov.ehealth.ehbox.core.v3;
using be.fgov.ehealth.ehbox.publication.protocol.v3;
using be.ehealth.businessconnector.ehbox.v3.session;
using be.fgov.ehealth.ehbox.consultation.protocol.v3;
using be.fgov.ehealth.technicalconnector.tests.utils;

namespace be.ehealth.businessconnector.ehboxv3.service
{
    [TestFixture]
    public class EhboxV3ServiceOoOIntegrationTest
    {    
        private static EhealthBoxServiceV3 service;
    
        private static java.util.List substitutes;
    
        private static BoxIdType usedSubstitute;
        
        private static Properties props = TestPropertiesLoader.getProperties(".\\be.ehealth.businessconnector.ehboxv3.test.properties",SupportedLanguages.NET.getAbbreviation());
    
        [SetUp]
        public static void initSession() {

            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
            if (EhboxTestUtilities.isDoctorTest(props) == true) {
            SessionInitializer.init(props, true,SupportedLanguages.NET.getAbbreviation());
            service = ServiceFactory.getEhealthBoxServiceV3();
            substitutes = new ArrayList();
            usedSubstitute = EhboxTestDataBuilder.getInssBoxIdUser2();
            substitutes.add(usedSubstitute);
            }
        }
        [TearDown]
        public void initOoOEnvironment() {
            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
            EhboxTestUtilities.deleteAllOutOfOfficesForCurrentUser(null);
            Session.getInstance().unloadSession();
        }

        [Test]
        public void testInsertOoOWithoutBoxInfo() {
            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
            try {
                InsertOoOResponse insertResponse = service.insertOoO(getInsertOoORequest(null));
                Assert.AreEqual("100", insertResponse.getStatus().getCode());
                String oooSavedId = insertResponse.getId();
                GetOoOListRequest getRequest = new GetOoOListRequest();
                getRequest.setBoxId(getBoxId());
                GetOoOListResponse getResponse = service.getOoOList(getRequest);
                Assert.AreEqual("100", getResponse.getStatus().getCode());
                DeleteOoORequest deleteRequest = new DeleteOoORequest();
                bool foundId = false;
                java.util.List ooos = getResponse.getOoOs();
                for (int i=0; i < ooos.size(); i++) {
                    OoO ooo = (OoO)ooos.get(i);
                    if (oooSavedId.Equals(ooo.getOoOId())) {
                        foundId = true;
                        deleteRequest.getOoOIds().add(oooSavedId);
                    }
                }
                Assert.IsTrue(foundId);
                deleteRequest.setBoxId(getBoxId());
                DeleteOoOResponse deleteResponse = service.deleteOoO(deleteRequest);
                Assert.AreEqual("100", deleteResponse.getStatus().getCode());
            } catch (java.lang.Exception e) {
                EhboxTestUtilities.logStackTrace(e);
                Assert.Fail(e.getMessage());
            }
        }


        [Test]
        public void test2Receiver() {
            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
            try {
                service.insertOoO(getInsertOoORequest(null));
                SendMessageRequest messageRequest = getMessageRequest();
                be.fgov.ehealth.ehbox.publication.protocol.v3.DestinationContextType destination = new be.fgov.ehealth.ehbox.publication.protocol.v3.DestinationContextType();
                destination.setId(EhboxTestDataBuilder.getInssUser1());
                destination.setQuality(QualityType.NURSE_SSIN.getQuality());
                destination.setType("SSIN");
                messageRequest.getDestinationContexts().add(destination);
                service.sendMessage(messageRequest);
                Assert.Fail("must return an exception");
            } catch (OoOPublicationException te) {
                Assert.IsTrue(te.getErrorCode().Equals("826"),"error code not 826");
                Map oooForwardInformation = te.getOooForwardInformation();
                Assert.IsNotNull(oooForwardInformation);
                Iterator iter = oooForwardInformation.keySet().iterator();
                while (iter.hasNext()) {
                    BoxIdType boxIdKey = (BoxIdType)iter.next();
                    java.util.List retrievedSubstituteList = (java.util.List) oooForwardInformation.get(boxIdKey);
                    Assert.AreEqual(1, retrievedSubstituteList.size());
                    Substitute retrievedSubstitute = (Substitute) retrievedSubstituteList.get(0);
                    Assert.AreEqual(usedSubstitute.getId(), retrievedSubstitute.getId());
                    Assert.AreEqual(usedSubstitute.getQuality(), retrievedSubstitute.getQuality());
                }
            } catch (java.lang.Exception e) {
                EhboxTestUtilities.logStackTrace(e);
                Assert.Fail(e.getMessage());
            }
        }

        [Test]
        public void testForward() {
            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
                try {
                    InsertOoORequest insertOoORequest = getInsertOoORequest(null);
                    service.insertOoO(insertOoORequest);

                    BoxIdType boxSubstituteId = (BoxIdType)substitutes.get(0);

                    try {
                        service.sendMessage(getMessageRequest());
                        Assert.Fail("must return an exception");
                    } catch (OoOPublicationException te) {
                        Assert.IsNotNull(te.getOooForwardInformation());
                        Assert.AreEqual(1, te.getOooForwardInformation().keySet().size());
                        BoxIdType receiverId = getBoxId();
                        BoxIdType responseId = (BoxIdType)te.getOooForwardInformation().keySet().iterator().next();
                        Assert.AreEqual(receiverId.getId(), responseId.getId());
                        Assert.AreEqual(receiverId.getQuality(), responseId.getQuality());
                        java.util.List list = (java.util.List)te.getOooForwardInformation().get(responseId);
                        Assert.AreEqual(1,list.size());
                        Substitute substituteId = (Substitute)list.get(0);
                        Assert.AreEqual(boxSubstituteId.getId(), substituteId.getId());
                        Assert.AreEqual(boxSubstituteId.getQuality(), substituteId.getQuality());
                    }
                } catch (java.lang.Exception e) {
                    EhboxTestUtilities.logStackTrace(e);
                    Assert.Fail(e.getMessage());
                }
    
        }

        [Test]
        public void testForceSendMessage() {
            Assume.That(EhboxTestUtilities.isDoctorTest(props) == true);
                try {
                    service.insertOoO(getInsertOoORequest(null));
                    SendMessageRequest messageRequest = getMessageRequest();
                    java.util.List list = messageRequest.getDestinationContexts();
                    for (int i = 0; i < list.size(); i++) {
                        EhboxIdentifierType identifier = (EhboxIdentifierType)list.get(i);
                        be.fgov.ehealth.ehbox.publication.protocol.v3.DestinationContextType destination = (be.fgov.ehealth.ehbox.publication.protocol.v3.DestinationContextType) identifier;
                        destination.setOoOProcessed(java.lang.Boolean.TRUE);
                    }
                    SendMessageResponse messageResponse = service.sendMessage(messageRequest);
                    Assert.AreEqual("100", messageResponse.getStatus().getCode());
                } catch (java.lang.Exception e) {
                    EhboxTestUtilities.logStackTrace(e);
                    Assert.Fail(e.getMessage());
                }
            
        }


        /**
         * @param boxId
         */
        private BoxIdType getBoxId() {
            return EhboxTestDataBuilder.getInssBoxIdUser1();

        }

        private InsertOoORequest getInsertOoORequest(BoxIdType boxId) {
            org.joda.time.DateTime startDate = new org.joda.time.DateTime();
            org.joda.time.DateTime endDate = startDate.plusWeeks(2);
            return BuilderFactory.getRequestBuilder().createInsertOoORequest(boxId, startDate, endDate, substitutes);
        }

        private SendMessageRequest getMessageRequest() {
            // Creating destination List
            java.util.List addresseeList = new ArrayList();
            Addressee addressee = new Addressee(IdentifierType.SSIN);
            addressee.setId(EhboxTestDataBuilder.getInssUser1());
            addressee.setQuality(QualityType.GENERAL_PRACTIONER_SSIN);
            addresseeList.add(addressee);

            // Creating the news
            SendMessageBuilder builder = BuilderFactory.getSendMessageBuilder();

            NewsMessage news = new NewsMessage();
            news.getDocument().setTitle("News " + new Date());
            news.getDocument().setContent("eureka".getBytes());
            news.setDestinations(addresseeList);
            // news.setSender(addressee);
            news.getDocument().setFilename("test.txt");
            news.setImportant(true);
            news.setEncrypted(false);

            return builder.buildMessage(news);
        }

        private static bool isDoctor() {
			java.util.List result = SAMLTokenUtils.getAttributeValue(Session.getInstance().getSession().getSAMLToken().getAssertion(), "doctor");
			return !result.isEmpty();
		}

    }


}
