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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.xml.ws.soap.SOAPFaultException;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.businessconnector.ehbox.api.domain.exception.EhboxBusinessConnectorException;
import be.ehealth.businessconnector.ehbox.v3.EhboxTestUtilities;
import be.ehealth.businessconnector.ehbox.v3.builders.BuilderFactory;
import be.ehealth.businessconnector.ehbox.v3.session.ServiceFactory;
import be.ehealth.technicalconnector.exception.ConnectorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.session.Session;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.GetMessageListResponseType;
import be.fgov.ehealth.ehbox.consultation.protocol.v3.Message;
import be.fgov.ehealth.ehbox.core.v3.BoxIdType;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;


/**
 * test that tries to empty the mailbox.
 * 
 * @author EHP
 * 
 */
public class CleanupMailboxIntegrationTest {

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


    @BeforeClass
    public static void removeOutOfOffices() throws Exception {
        Properties props = TestPropertiesLoader.getProperties("/be.ehealth.businessconnector.ehboxv3.test.properties");
        SessionInitializer.init(props, true);
    }


    @AfterClass
    public static void unloadSession() throws Exception {
        Session.getInstance().unloadSession();
    }

    @Test
    public void cleanOutOfOfficesTest() throws Exception {
        EhboxTestUtilities.deleteAllOutOfOfficesForCurrentUser(null);
    }

    @Test
    public void cleanInboxTest() throws Exception {
        EhboxTestUtilities.deleteAllMessagesForSource("INBOX", null);
    }

    /**
     * @throws ConnectorException
     */
    public static void deleteAllMessagesForEachSourceWithAllEhboxesMessageList() throws ConnectorException {
        for (String source : EhboxTestUtilities.getListOfAllSources()) {
            GetMessageListResponseType allEhboxesMessagesList = ServiceFactory.getEhealthBoxServiceV3().getAllEhboxesMessagesList(BuilderFactory.getRequestBuilder().createAllEhboxesMessagesListRequest(source));
            Map<String, Set<String>> messagesToDeleteBySource = createMapWithMessagesToDelete(allEhboxesMessagesList);
            for (String sourceToUse : messagesToDeleteBySource.keySet()) {
                Set<String> messageIdsSet = messagesToDeleteBySource.get(sourceToUse);
                LOG.debug("initializeMailbox : destination for messageToDelete for source " + source + " and boxType: " + sourceToUse + " number " + messageIdsSet.size());
                List<String> messageidsList = new ArrayList<String>(messageIdsSet);
                try {
                    ServiceFactory.getEhealthBoxServiceV3().deleteMessage(BuilderFactory.getRequestBuilder().createDeleteMessageRequest(source, revertToBoxIdtype(sourceToUse), messageidsList));
                } catch (EhboxBusinessConnectorException e) {
                    LOG.error("initializeMailboxesInKnownCondition business exception: error while trying to delete " + e.getErrorCode());
                } catch (SOAPFaultException e) {
                    LOG.error("initializeMailboxesInKnownCondition soap fault exception: error while trying to delete " + e.getMessage());
                } catch (TechnicalConnectorException e) {
                    StringBuilder sb = new StringBuilder("could not delete one or more messages from this list : [");
                    for (String string : messageidsList) {
                        sb.append(string).append(" ");
                    }
                    sb.append("]  ");
                    sb.append("error : ").append(e.getMessage());
                    LOG.error(sb.toString());
                }
            }
        }
    }

    /**
     * @param allEhboxesMessagesList
     * @return
     */
    public static Map<String, Set<String>> createMapWithMessagesToDelete(GetMessageListResponseType allEhboxesMessagesList) {
        Map<String, Set<String>> messagesToDeleteBySource = new HashMap<String, Set<String>>();
        for (Message message : allEhboxesMessagesList.getMessages()) {
            EhboxTestUtilities.logMessage(message);
            Set<String> messagesToDelete = messagesToDeleteBySource.get(message.getDestination());
            if (messagesToDelete == null) {
                messagesToDelete = new HashSet<String>();
                BoxIdType mapDestinationToBoxIdType = EhboxTestUtilities.mapDestinationToBoxIdType(message.getDestination());
                messagesToDeleteBySource.put(convertToComparableString(mapDestinationToBoxIdType), messagesToDelete);
            }
            messagesToDelete.add(message.getMessageId());
        }
        return messagesToDeleteBySource;
    }

    private static String convertToComparableString(BoxIdType sourceToUse) {
        return sourceToUse.getId() + " " + sourceToUse.getQuality() + " " + sourceToUse.getType();
    }

    private static BoxIdType revertToBoxIdtype(String boxIdtypeString) {
        String[] split = boxIdtypeString.split(" ");
        BoxIdType boxIdType = new BoxIdType();
        boxIdType.setId(split[0]);
        boxIdType.setQuality(split[1]);
        boxIdType.setType(split[2]);
        return boxIdType;
    }

    @Test
    public void testDeleteProblem() throws Exception {
        String source = "SENTBOX";
        GetMessageListResponseType allEhboxesMessagesList = ServiceFactory.getEhealthBoxServiceV3().getAllEhboxesMessagesList(BuilderFactory.getRequestBuilder().createAllEhboxesMessagesListRequest(source));
        Map<String, Set<String>> messagesToDeleteBySource = createMapWithMessagesToDelete(allEhboxesMessagesList);

        for (String sourceToUse : messagesToDeleteBySource.keySet()) {
            Set<String> messageIdsSet = messagesToDeleteBySource.get(sourceToUse);
            LOG.debug("initializeMailbox : destination for messageToDelete for source " + source + " and boxType: " + sourceToUse + " number " + messageIdsSet.size());
            List<String> messageidsList = new ArrayList<String>(messageIdsSet);
            try {
                ServiceFactory.getEhealthBoxServiceV3().deleteMessage(BuilderFactory.getRequestBuilder().createDeleteMessageRequest(source, revertToBoxIdtype(sourceToUse), messageidsList));
            } catch (EhboxBusinessConnectorException e) {
                LOG.error("initializeMailboxesInKnownCondition business exception: error while trying to delete " + e.getErrorCode());
            } catch (SOAPFaultException e) {
                LOG.error("initializeMailboxesInKnownCondition soap fault exception: error while trying to delete " + e.getMessage());
            } catch (TechnicalConnectorException e) {
                StringBuilder sb = new StringBuilder("could not delete one or more messages from this list : [");
                for (String string : messageidsList) {
                    sb.append(string).append(" ");
                }
                sb.append("]  ");
                sb.append("boxId should be: " + revertToBoxIdtype(sourceToUse).getId() + ", ");
                sb.append("error : ").append(e.getMessage());
                LOG.error(sb.toString());
            }
        }


        // String source = "SENTBOX";
        // GetMessageListResponseType allEhboxesMessagesList =
        // ServiceFactory.getEhealthBoxServiceV3().getAllEhboxesMessagesList(BuilderFactory.getRequestBuilder().createAllEhboxesMessagesListRequest(source));
        // Map<String, Set<String>> messagesToDeleteBySource = createMapWithMessagesToDelete(allEhboxesMessagesList);
        // for (String sourceToUse : messagesToDeleteBySource.keySet()) {
        // Set<String> messageIdsSet = messagesToDeleteBySource.get(sourceToUse);
        // LOG.debug("initializeMailbox : destination for messageToDelete for source " + source + " and boxType: " + sourceToUse +
        // " number " + messageIdsSet.size());
        // List<String> messageidsList = new ArrayList<String>(messageIdsSet);
        // try {
        // for (String messageId : messageidsList) {
        // System.out.println("source : " + source + ", source to use : " + sourceToUse + ", message :" + messageId);
        // ServiceFactory.getEhealthBoxServiceV3().deleteMessage(BuilderFactory.getRequestBuilder().createDeleteMessageRequest(source,
        // revertToBoxIdtype(sourceToUse), messageId));
        // }
        // } catch (EhboxBusinessConnectorException e) {
        // Assert.fail("initializeMailboxesInKnownCondition business exception: error while trying to delete " + e.getErrorCode());
        // } catch (SOAPFaultException e) {
        // Assert.fail("initializeMailboxesInKnownCondition soap fault exception: error while trying to delete " + e.getMessage());
        // }
        // }
    }

}
