/* BdfServer_DirectoryStorage - Copyright (c) 2015-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.storage.directory.implementations;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.api.storage.StorageCheck;
import fr.exemole.bdfserver.api.storage.UiStorage;
import fr.exemole.bdfserver.api.ui.UiComponents;
import fr.exemole.bdfserver.storage.directory.StorageDirectory;
import fr.exemole.bdfserver.storage.directory.bdfdata.BdfdataConstants;
import fr.exemole.bdfserver.tools.storage.StorageFile;
import fr.exemole.bdfserver.tools.ui.UiComponentsBuilder;
import fr.exemole.bdfserver.tools.ui.dom.UiComponentsDOMReader;
import fr.exemole.bdfserver.xml.ui.UiComponentsXMLPart;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import net.fichotheque.SubsetKey;
import net.mapeadores.util.html.HtmlCleaner;
import net.mapeadores.util.io.FileUtils;
import net.mapeadores.util.logging.MultiMessageHandler;
import net.mapeadores.util.xml.AppendableXMLWriter;
import net.mapeadores.util.xml.XMLUtils;
import org.w3c.dom.Document;


/**
 *
 * @author Vincent Calame
 */
public class UiStorageImpl implements UiStorage {

    private final StorageDirectory bdfdataDirectory;
    private final HtmlCleaner htmlCleaner;
    private final String rootPath = BdfdataConstants.CONF + File.separator + "ui";
    private final String corpusRootPath = BdfdataConstants.CONF + File.separator + "ui" + File.separator + "corpus";

    public UiStorageImpl(StorageDirectory bdfdataDirectory, HtmlCleaner htmlCleaner) {
        this.bdfdataDirectory = bdfdataDirectory;
        this.htmlCleaner = htmlCleaner;
    }

    @Override
    public HtmlCleaner getHtmlCleaner() {
        return htmlCleaner;
    }

    public Map<SubsetKey, StorageCheck.UiCheck> check(MultiMessageHandler messageHandler) {
        Map<SubsetKey, StorageCheck.UiCheck> result = new HashMap<SubsetKey, StorageCheck.UiCheck>();
        File corpusDir = bdfdataDirectory.getDataDir(corpusRootPath);
        if (!corpusDir.exists()) {
            return result;
        }
        for (File subsetDir : corpusDir.listFiles()) {
            if (subsetDir.isDirectory()) {
                try {
                    SubsetKey subsetKey = SubsetKey.parse(SubsetKey.CATEGORY_CORPUS, subsetDir.getName());
                    File mainFile = new File(subsetDir, "_main.xml");
                    if (mainFile.exists()) {
                        UiComponentsBuilder uiComponentsBuilder = new UiComponentsBuilder();
                        StorageFile storageFile = bdfdataDirectory.getStorageFile(corpusRootPath + File.separator + subsetDir.getName() + File.separator + "_main.xml");
                        messageHandler.setCurrentSource(storageFile.toURI());
                        Document doc = storageFile.readDocument();
                        UiComponentsDOMReader reader = new UiComponentsDOMReader(uiComponentsBuilder, htmlCleaner, messageHandler);
                        reader.readUiComponents(doc.getDocumentElement());
                        InternalUiCheck uiCheck = new InternalUiCheck(uiComponentsBuilder.toUiComponents());
                        result.put(subsetKey, uiCheck);
                    }
                } catch (ParseException pe) {

                }
            }
        }
        return result;
    }

    @Override
    public void saveUiComponents(SubsetKey subsetKey, UiComponents uiComponents) {
        StorageFile storageFile = getStorageFile(subsetKey, "_main.xml");
        try (BufferedWriter buf = storageFile.getWriter()) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            UiComponentsXMLPart xmlPart = new UiComponentsXMLPart(xmlWriter);
            xmlPart.appendUiComponents(uiComponents);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    @Override
    public void removeUiComponents(SubsetKey subsetKey) {
        File subsetDir = bdfdataDirectory.getDataDir(corpusRootPath + File.separator + subsetKey.getSubsetName());
        if (subsetDir.exists()) {
            for (File file : subsetDir.listFiles()) {
                if (file.isFile()) {
                    getStorageFile(subsetKey, file.getName()).delete();
                }
            }
            try {
                FileUtils.forceDelete(subsetDir);
            } catch (IOException ioe) {
                throw new BdfStorageException(ioe);
            }
        }
    }

    private StorageFile getStorageFile(SubsetKey subsetKey, String name) {
        return bdfdataDirectory.getStorageFile(corpusRootPath + File.separator + subsetKey.getSubsetName() + File.separator + name);
    }


    private static class InternalUiCheck implements StorageCheck.UiCheck {

        private final UiComponents mainUiComponents;

        private InternalUiCheck(UiComponents mainUiComponents) {
            this.mainUiComponents = mainUiComponents;
        }

        @Override
        public UiComponents getMainUiComponents() {
            return mainUiComponents;
        }

    }

}
