/* BdfServer - Copyright (c) 2019-2025 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.tools.balayage;

import fr.exemole.bdfserver.api.storage.BalayageStorage;
import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.api.storage.StorageContent;
import java.io.IOException;
import java.io.InputStream;
import net.fichotheque.exportation.balayage.BalayageDef;
import net.fichotheque.exportation.balayage.BalayageDescription;
import net.fichotheque.tools.exportation.balayage.BalayageContentDescriptionBuilder;
import net.fichotheque.tools.exportation.balayage.BalayageDescriptionBuilder;
import net.fichotheque.tools.exportation.balayage.dom.IncludeCatalogDOMReader;
import net.mapeadores.util.logging.LogUtils;
import net.mapeadores.util.xml.DOMUtils;
import net.mapeadores.util.xml.DocumentFragmentHolderBuilder;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;


/**
 *
 * @author Vincent Calame
 */
public final class BalayageCompiler {

    private final static String SEVERE_XML = "severe.xml";

    private BalayageCompiler() {
    }

    public static BalayageDescription compile(BalayageStorage.Unit storageUnit) {
        BalayageDef balayageDef = storageUnit.getBalayageDef();
        String balayageName = balayageDef.getName();
        BalayageDescriptionBuilder balayageDescriptionBuilder = new BalayageDescriptionBuilder(balayageDef);
        StorageContent includeCatalog = getStorageContent(storageUnit, "include-catalog.xml");
        if (includeCatalog != null) {
            BalayageContentDescriptionBuilder builder = new BalayageContentDescriptionBuilder(balayageName, includeCatalog.getPath());
            try (InputStream is = includeCatalog.getInputStream()) {
                Document document = DOMUtils.parseDocument(is);
                DocumentFragmentHolderBuilder documentFragmentHolderBuilder = new DocumentFragmentHolderBuilder();
                IncludeCatalogDOMReader.init(documentFragmentHolderBuilder, LogUtils.NULL_MESSAGEHANDLER)
                        .read(document.getDocumentElement());
                balayageDescriptionBuilder.setIncludeCatalog(documentFragmentHolderBuilder.toDocumentFragmentHolder());
            } catch (SAXException saxe) {
                LogUtils.handleSAXException(SEVERE_XML, saxe, builder.getLineMessageHandler());
            } catch (IOException ioe) {
                throw new BdfStorageException(ioe);
            }
            balayageDescriptionBuilder.addBalayageContentDescription(builder.toBalayageContentDescription());
        }
        for (StorageContent storageContent : storageUnit.getStorageContentList()) {
            BalayageContentDescriptionBuilder builder = new BalayageContentDescriptionBuilder(balayageName, storageContent.getPath());
            try (InputStream is = storageContent.getInputStream()) {
                DOMUtils.parseDocument(is);
            } catch (SAXException saxe) {
                LogUtils.handleSAXException(SEVERE_XML, saxe, builder.getLineMessageHandler());
            } catch (IOException ioe) {
                throw new BdfStorageException(ioe);
            }
            balayageDescriptionBuilder.addBalayageContentDescription(builder.toBalayageContentDescription());
        }
        return balayageDescriptionBuilder.toBalayageDescription();
    }

    private static StorageContent getStorageContent(BalayageStorage.Unit storageUnit, String path) {
        for (StorageContent storageContent : storageUnit.getStorageContentList()) {
            if (storageContent.getPath().equals(path)) {
                return storageContent;
            }
        }
        return null;
    }

}
