/* BdfServer_Email - Copyright (c) 2011-2023 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.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
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.SimpleTemplate;
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.ExtractionDefFilterEngine;
import net.fichotheque.tools.extraction.ExtractionEngine;
import net.fichotheque.tools.extraction.ExtractionEngineUtils;
import net.fichotheque.extraction.ExtractParameters;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.io.IOUtils;


/**
 *
 * @author Vincent Calame
 */
public class SimpleTemplateDataSource implements DataSource {

    private final String name;
    private final String mimeType;
    private final String charset;
    private final String content;

    private SimpleTemplateDataSource(String name, String mimeType, String charset, String content) {
        this.name = name;
        this.mimeType = mimeType;
        this.charset = charset;
        this.content = content;
    }


    @Override
    public String getContentType() {
        return mimeType + ";charset=" + charset;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return IOUtils.toInputStream(content, charset);
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        throw new IOException("no editable source");
    }

    public String getMimeType() {
        return mimeType;
    }

    public String getContent() {
        return content;
    }

    public static SimpleTemplateDataSource newFicheInstance(BdfParameters bdfParameters, FicheMeta ficheMeta, @Nullable String templateName) {
        SubsetKey corpusKey = ficheMeta.getSubsetKey();
        String baseName = corpusKey.getSubsetName() + "-" + String.valueOf(ficheMeta.getId());
        TemplateKey templateKey = getTemplateKey(new TransformationKey(corpusKey), templateName, bdfParameters);
        ExtractionContext extractionContext = bdfParameters.getDefaultExtractionContext();
        return transform(bdfParameters, templateKey, baseName, extractionContext, ficheMeta, null);
    }

    public static SimpleTemplateDataSource newCompilationInstance(BdfParameters bdfParameters, Fiches fiches, String templateName) {
        String baseName = "compilation";
        TemplateKey templateKey = getTemplateKey(TransformationKey.COMPILATION_INSTANCE, templateName, bdfParameters);
        ExtractionContext extractionContext = bdfParameters.getDefaultExtractionContext();
        return transform(bdfParameters, templateKey, baseName, extractionContext, null, fiches);
    }

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

    private static SimpleTemplateDataSource transform(BdfParameters bdfParameters, TemplateKey templateKey, String baseName, ExtractionContext extractionContext, Object dynamicObject, Fiches staticFiches) {
        BdfServer bdfServer = bdfParameters.getBdfServer();
        TransformationManager transformationManager = bdfServer.getTransformationManager();
        SimpleTemplate simpleTemplate = transformationManager.getSimpleTemplate(templateKey, true);
        ExtractionDef extractionDef = simpleTemplate.getCustomExtractionDef();
        if (extractionDef == null) {
            extractionDef = DefaultExtractionDefFactory.newInstance(bdfServer, templateKey.getTransformationKey(), simpleTemplate.getAttributes());
        }
        extractionDef = ExtractionDefFilterEngine.run(extractionDef, extractionContext);
        ExtractionSource extractionSource = ExtractionEngineUtils.getExtractionSource(dynamicObject, extractionContext, extractionDef, staticFiches);
        ExtractParameters extractParameters = BdfTransformationUtils.buildExtractParameters(extractionContext, simpleTemplate.getAttributes(), bdfParameters, null);
        String extractionString = ExtractionEngine.init(extractParameters, extractionDef).run(extractionSource);
        TransformerParameters transformerParameters = TransformerParameters.build(bdfParameters)
                .check(simpleTemplate.getAttributes())
                .put(TransformationConstants.INCLUDESCRIPTS_PARAMETER, "");
        String mimeType = simpleTemplate.getMimeType();
        String extension = bdfServer.getMimeTypeResolver().getPreferredExtension(mimeType);
        if (extension == null) {
            extension = "html";
        }
        String content = simpleTemplate.transform(extractionString, transformerParameters.getMap());
        return new SimpleTemplateDataSource(baseName + "." + extension, mimeType, simpleTemplate.getCharset(), content);
    }

}
