/* BdfServer_Email - Copyright (c) 2021-2024 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.email.datasource;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.exportation.transformation.TransformationConstants;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.managers.TransformationManager;
import fr.exemole.bdfserver.tools.exportation.transformation.BdfTransformationUtils;
import fr.exemole.bdfserver.tools.exportation.transformation.DefaultExtractionDefFactory;
import fr.exemole.bdfserver.tools.exportation.transformation.TransformerParameters;
import fr.exemole.bdfserver.tools.users.BdfUserUtils;
import java.text.ParseException;
import javax.activation.DataSource;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.exportation.transformation.NoDefaultTemplateException;
import net.fichotheque.exportation.transformation.StreamTemplate;
import net.fichotheque.exportation.transformation.TemplateKey;
import net.fichotheque.exportation.transformation.TransformationKey;
import net.fichotheque.extraction.ExtractionContext;
import net.fichotheque.extraction.ExtractionSource;
import net.fichotheque.extraction.def.ExtractionDef;
import net.fichotheque.tools.extraction.ExtractionEngine;
import net.fichotheque.tools.extraction.ExtractionEngineUtils;
import net.fichotheque.extraction.ExtractParameters;
import net.mapeadores.util.text.ValidExtension;


/**
 *
 * @author Vincent Calame
 */
public class StreamDataSourceFactory {

    private StreamDataSourceFactory() {

    }

    public static DataSource newFicheInstance(BdfParameters bdfParameters, FicheMeta ficheMeta, ValidExtension extension, String templateName) {
        SubsetKey corpusKey = ficheMeta.getSubsetKey();
        String name = corpusKey.getSubsetName() + "-" + String.valueOf(ficheMeta.getId()) + "." + extension.toString();
        TemplateKey templateKey = getTemplateKey(new TransformationKey(corpusKey), extension, templateName, bdfParameters);
        ExtractionContext extractionContext = bdfParameters.getDefaultExtractionContext();
        StreamTemplate streamTemplate = getStreamTemplate(bdfParameters.getBdfServer(), templateKey);
        if (streamTemplate instanceof StreamTemplate.Xslt) {
            return initXslt((StreamTemplate.Xslt) streamTemplate, bdfParameters, templateKey, name, extractionContext, ficheMeta, null);
        } else {
            throw new IllegalStateException("unknown streamTemplate Type");
        }
    }

    public static DataSource newCompilationInstance(BdfParameters bdfParameters, Fiches fiches, ValidExtension extension, String templateName) {
        String name = "compilation" + "." + extension.toString();
        ExtractionContext extractionContext = bdfParameters.getDefaultExtractionContext();
        TemplateKey templateKey = getTemplateKey(TransformationKey.COMPILATION_INSTANCE, extension, templateName, bdfParameters);
        StreamTemplate streamTemplate = getStreamTemplate(bdfParameters.getBdfServer(), templateKey);
        if (streamTemplate instanceof StreamTemplate.Xslt) {
            return initXslt((StreamTemplate.Xslt) streamTemplate, bdfParameters, templateKey, name, extractionContext, null, fiches);
        } else {
            throw new IllegalStateException("unknown streamTemplate Type");
        }
    }

    private static TemplateKey getTemplateKey(TransformationKey transformationKey, ValidExtension extension, String templateName, BdfParameters bdfParameters) {
        if (templateName == null) {
            return BdfUserUtils.getStreamTemplateKey(bdfParameters, transformationKey, extension);
        }
        TemplateKey templateKey;
        try {
            templateKey = TemplateKey.parse(transformationKey, extension, templateName);
        } catch (ParseException pe) {
            templateKey = TemplateKey.toDefault(transformationKey, extension);
        }
        return templateKey;
    }

    private static StreamTemplate getStreamTemplate(BdfServer bdfServer, TemplateKey templateKey) {
        TransformationManager transformationManager = bdfServer.getTransformationManager();
        StreamTemplate streamTemplate;
        try {
            streamTemplate = transformationManager.getStreamTemplate(templateKey, true);
        } catch (NoDefaultTemplateException ndte) {
            throw new IllegalStateException("Bad streamTemplateName and no default: " + templateKey);
        }
        return streamTemplate;
    }

    private static DataSource initXslt(StreamTemplate.Xslt streamTemplate, BdfParameters bdfParameters, TemplateKey templateKey, String name, ExtractionContext extractionContext, Object dynamicObject, Fiches staticFiches) {
        ExtractionDef extractionDef = streamTemplate.getCustomExtractionDef();
        if (extractionDef == null) {
            extractionDef = DefaultExtractionDefFactory.newInstance(bdfParameters.getBdfServer(), templateKey.getTransformationKey(), streamTemplate.getAttributes());
        }
        ExtractionSource extractionSource = ExtractionEngineUtils.getExtractionSource(dynamicObject, extractionContext, extractionDef, staticFiches);
        ExtractParameters extractParameters = BdfTransformationUtils.buildExtractParameters(extractionContext, streamTemplate.getAttributes(), bdfParameters, null);
        String extractionString = ExtractionEngine.init(extractParameters, extractionDef).run(extractionSource);
        TransformerParameters transformerParameters = TransformerParameters.build(bdfParameters)
                .check(streamTemplate.getAttributes())
                .put(TransformationConstants.INCLUDESCRIPTS_PARAMETER, "");
        return new XsltStreamDataSource(name, streamTemplate, extractionString, transformerParameters);
    }

}
