/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.chapterIV.integration;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;

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

import be.ehealth.businessconnector.chapterIV.builders.BuilderFactory;
import be.ehealth.businessconnector.chapterIV.builders.ResponseBuilder;
import be.ehealth.businessconnector.chapterIV.exception.ChapterIVBusinessConnectorException;
import be.ehealth.businessconnector.chapterIV.session.ChapterIVService;
import be.ehealth.technicalconnector.exception.SoaErrorException;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.session.Session;
import be.ehealth.technicalconnector.utils.MarshallerHelper;
import be.fgov.ehealth.chap4.core.v1.DetailType;
import be.fgov.ehealth.chap4.core.v1.FaultType;
import be.fgov.ehealth.errors.core.v1.LocalisedStringType;
import be.fgov.ehealth.errors.soa.v1.SOAErrorType;
import be.fgov.ehealth.standards.kmehr.schema.v1.FolderType;
import be.fgov.ehealth.technicalconnector.tests.session.SessionDestroyer;
import be.fgov.ehealth.technicalconnector.tests.session.SessionInitializer;
import be.fgov.ehealth.technicalconnector.tests.utils.SAMLTokenUtils;
import be.fgov.ehealth.technicalconnector.tests.utils.TestPropertiesLoader;


/**
 * abstract super class for ChapterIv integration tests.
 * 
 * @author EHP
 * 
 */
public abstract class AbstractChapterIVTestBase {

    private static ResponseBuilder responseBuilder;

    private static Properties props = null;

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


    @BeforeClass
    public static void setup() throws Exception {
        SessionDestroyer.destroy();
        props = TestPropertiesLoader.getProperties("/be.ehealth.businessconnector.chapterIV.test.properties");
        SessionInitializer.init(props);
        responseBuilder = BuilderFactory.getBuilderFactoryForSession().getResponseBuilder();
    }

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

    /**
     * @param service
     * @param e
     */
    protected void processChapterIvBusinessException(ChapterIVService service, ChapterIVBusinessConnectorException e) {
        StringBuilder sb = new StringBuilder();
        appendAndLog(sb, e.getMessage());
        appendAndLog(sb, e.getMessage());

        SOAErrorType soaError = e.getSOAError();
        if (soaError != null) {
            String errorCode = soaError.getCode();
            appendAndLog(sb, "ChapterIVIntegrationTest.test" + service + "Request: error : " + errorCode);
            appendAndLog(sb, "contact :" + soaError.getContact());
            appendAndLog(sb, "environment : " + soaError.getEnvironment());
            appendAndLog(sb, "id :" + soaError.getId());
            appendAndLog(sb, "Origin " + soaError.getOrigin());
            appendAndLog(sb, "isRetrye : " + soaError.isRetry());
            for (LocalisedStringType localisedString : soaError.getMessages()) {
                appendAndLog(sb, "message : lang=" + localisedString.getLang() + " and value = " + localisedString.getValue());
            }
        }
        Assert.fail(sb.toString());
    }

    /**
     * @param e
     */
    protected void processError(SoaErrorException e, String service) {
        StringBuilder sb = new StringBuilder();
        String errorCode = e.getErrorCode();
        appendAndLog(sb, "ChapterIVIntegrationTest.test" + service + "Request: error : " + errorCode);
        FaultType fault = responseBuilder.retrieveReturnInfo(e.getResponseType());
        String errorMessage = "";
        if (fault.getMessage() != null) {
            errorMessage = fault.getMessage().getValue();
        }
        appendAndLog(sb, "errorMessage :" + errorMessage);
        for (DetailType detail : fault.getDetails()) {
            appendAndLog(sb, "detail : " + detail.getDetailCode() + " " + detail.getDetailSource() + " " + detail.getLocation() + " " + (detail.getMessage() == null ? "no messages" : detail.getMessage().getValue()));
        }
        Assert.fail(sb.toString());
    }

    /**
     * @param xmlResourceInputStream
     * @return
     * @throws TechnicalConnectorException
     */
    protected FolderType parseFolderType(InputStream xmlResourceInputStream) throws TechnicalConnectorException {
        MarshallerHelper<FolderType, FolderType> folderTypeMarshaller = new MarshallerHelper<FolderType, FolderType>(FolderType.class, FolderType.class);
        return folderTypeMarshaller.toObject(xmlResourceInputStream);
    }

    /**
     * @param sb
     * @param message
     */
    protected void appendAndLog(StringBuilder sb, String message) {
        LOG.error(message);
        sb.append(message).append("\n");
    }


    /**
     * @return the responseBuilder
     */
    public static ResponseBuilder getResponseBuilder() {
        return responseBuilder;
    }

    /**
     * @return
     */
    protected static boolean isDoctor() throws TechnicalConnectorException {
        List<String> result = SAMLTokenUtils.getAttributeValue(Session.getInstance().getSession().getSAMLToken().getAssertion(), "doctor");
        return !result.isEmpty();
    }

}
