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

import java.util.List;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.ehealth.business.common.domain.Patient;
import be.ehealth.business.kmehrcommons.HcPartyUtil;
import be.ehealth.business.mycarenetcommons.builders.BlobBuilderFactory;
import be.ehealth.business.mycarenetcommons.builders.CommonBuilder;
import be.ehealth.business.mycarenetcommons.domain.Blob;
import be.ehealth.business.mycarenetcommons.domain.Routing;
import be.ehealth.business.mycarenetcommons.mapper.SendRequestMapper;
import be.ehealth.businessconnector.tarification.builder.RequestBuilder;
import be.ehealth.businessconnector.tarification.builder.TarificationRequestBuilderFactory;
import be.ehealth.businessconnector.tarification.helper.ResponseHelper;
import be.ehealth.businessconnector.tarification.session.TarificationSessionService;
import be.ehealth.businessconnector.tarification.session.TarificationSessionServiceFactory;
import be.ehealth.technicalconnector.exception.ConnectorException;
import be.ehealth.technicalconnector.idgenerator.IdGeneratorFactory;
import be.ehealth.technicalconnector.utils.ConnectorXmlUtils;
import be.ehealth.technicalconnector.utils.MarshallerHelper;
import be.fgov.ehealth.messageservices.core.v1.RetrieveTransactionRequest;
import be.fgov.ehealth.messageservices.core.v1.RetrieveTransactionResponse;
import be.fgov.ehealth.mycarenet.commons.core.v2.BlobType;
import be.fgov.ehealth.mycarenet.commons.protocol.v2.TarificationConsultationRequest;
import be.fgov.ehealth.mycarenet.commons.protocol.v2.TarificationConsultationResponse;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDERRORMYCARENET;
import be.fgov.ehealth.standards.kmehr.schema.v1.ErrorMyCarenetType;
import be.fgov.ehealth.standards.kmehr.schema.v1.Kmehrmessage;


/**
 * class containing the code example for the usage of the tarification connector.
 * 
 * @author EH076
 * 
 * @since
 * 
 */
public class CodeExampleUsage {

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

    /**
     * @param args
     */
    public static void codeExampleTest() {
        try {
            // each project is identified
            final String projectName = "mcn.tarification";
            // Instantiate builders
            CommonBuilder mycarenetCommonBuilder = be.ehealth.business.mycarenetcommons.builders.RequestBuilderFactory.getCommonBuilder(projectName);

            String inputReference = IdGeneratorFactory.getIdGenerator("xsid").generateId(); // generate a unique identifier to identify your
                                                                                            // message ( inputReference
            //

            // filling this request is out of scope of the connector, but some utility methods are available in
            // be.ehealth.business.kmehrcommons.HcPartyUtil.
            RetrieveTransactionRequest request = new RetrieveTransactionRequest();
            // ...
            request.getRequest().getAuthor().getHcparties().addAll(HcPartyUtil.createAuthorHcParties(projectName));
            request.getSelect().getTransaction().getAuthor().getHcparties().addAll(HcPartyUtil.createAuthorHcParties(projectName));
            String kmehrIdString = HcPartyUtil.createKmehrIdString(projectName, inputReference); // generates a kmehr id with the id of the
                                                                                                 // author as first part , and the
                                                                                                 // inputReference as second part , as
                                                                                                 // required in spec
            request.getRequest().getId().setValue(kmehrIdString); // just example , you should probably create the full id first
            // ...


            // the only input for the detail that is needed is the bytearray containing the businnes xml.
            byte[] businessContent = ConnectorXmlUtils.toByteArray(request);
            RequestBuilder requestBuilder = TarificationRequestBuilderFactory.getRequestObjectBuilder();
            // there are 2 ways to create the request
            // FIRST : with minimal input , only a minimal input is needed.
            // create routing element : this will determine where to send the message , ( see documentation mycarenet and javadoc )
            // Retrieve patient info from eid card, or create the Patient object in your own code
            Patient patient = be.ehealth.business.common.util.EidUtils.readFromEidCard();
            DateTime referenceDate = new DateTime(); // create the reference date for the request ( see documentation mycarenet )
            Routing routing = mycarenetCommonBuilder.createRouting(patient, referenceDate); // more info :see javadoc
            TarificationConsultationRequest consultationRequest = requestBuilder.buildConsultationRequest(routing, businessContent, inputReference);
            TarificationSessionService service = TarificationSessionServiceFactory.getTarificationSession();
            TarificationConsultationResponse consultTarificationResponse = service.consultTarification(consultationRequest);
            // other option :

            // there are utility methods , preconfigured for tarification to help extract the business response
            BlobType detail = consultTarificationResponse.getReturn().getDetail();
            // the blobtype can be mapped to a common domain class for the connector
            Blob blob = SendRequestMapper.mapBlobTypeToBlob(detail);
            // you can check the validity of the blob and retrieve the content ( deflated and decoded if needed )
            byte[] content = BlobBuilderFactory.getBlobBuilder("mcn.tarification").checkAndRetrieveContent(blob);
            // the content ( as bytearray ) can be converted to the jaxb object with a MarshallerHelper configured for that class
            MarshallerHelper<RetrieveTransactionResponse, RetrieveTransactionResponse> helper = new MarshallerHelper<RetrieveTransactionResponse, RetrieveTransactionResponse>(RetrieveTransactionResponse.class, RetrieveTransactionResponse.class);
            RetrieveTransactionResponse commonInputResponse = helper.toObject(content);
            // this helper class has also some other useFull methods ( toString , ... )

            // tarification contains a ResponseHelper class that will validate the xml of the response.
            ResponseHelper.validateResponse(commonInputResponse);

            // handle the potential errors
            boolean isComplete = commonInputResponse.getAcknowledge().isIscomplete();
            System.out.print("isComplete : " + isComplete);
            List<ErrorMyCarenetType> errors = commonInputResponse.getAcknowledge().getErrors();
            for (ErrorMyCarenetType errorMyCarenetType : errors) {
                // show error to user??? the meaning of the error codes can be found in the mycarenet documentation
                StringBuffer errorCodes = new StringBuffer();
                for (CDERRORMYCARENET errorCode : errorMyCarenetType.getCds()) {
                    errorCodes.append(" ").append(errorCode.getValue());
                }
                LOG.debug("error : codes :" + errorCodes.toString() + ", description : " + errorMyCarenetType.getDescription().getValue());
            }
            Kmehrmessage kmehrmessage = commonInputResponse.getKmehrmessage();
            LOG.debug("kmerhMessage : " + ConnectorXmlUtils.toString(kmehrmessage));
            // handle kmerhMessage

        } catch (ConnectorException e) {
            LOG.error("error occurred : " + e.getMessage());
            // handle these exceptions
        }


    }


}
