/* BdfServer_DirectoryStorage - Copyright (c) 2013-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.bdfdata;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.api.users.BdfUserPrefs;
import fr.exemole.bdfserver.storage.directory.StorageDirectory;
import fr.exemole.bdfserver.tools.storage.StorageFile;
import fr.exemole.bdfserver.tools.storage.StorageUtils;
import fr.exemole.bdfserver.xml.users.BdfUserPrefsXMLPart;
import java.io.BufferedWriter;
import java.io.IOException;
import net.fichotheque.EditOrigin;
import net.fichotheque.Subset;
import net.fichotheque.SubsetKey;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.Document;
import net.fichotheque.album.Album;
import net.fichotheque.album.Illustration;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.fiche.FicheAPI;
import net.fichotheque.metadata.FichothequeMetadata;
import net.fichotheque.sphere.Redacteur;
import net.fichotheque.sphere.Sphere;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.xml.storage.AddendaMetadataXMLPart;
import net.fichotheque.xml.storage.AlbumMetadataXMLPart;
import net.fichotheque.xml.storage.AttributesStorageXMLPart;
import net.fichotheque.xml.storage.CorpusMetadataXMLPart;
import net.fichotheque.xml.storage.JunctionStorageXMLPart;
import net.fichotheque.xml.storage.DocumentStorageXMLPart;
import net.fichotheque.xml.storage.FicheStorageXMLPart;
import net.fichotheque.xml.storage.FichothequeMetadataXMLPart;
import net.fichotheque.xml.storage.IllustrationStorageXMLPart;
import net.fichotheque.xml.storage.MotcleStorageXMLPart;
import net.fichotheque.xml.storage.RedacteurStorageXMLPart;
import net.fichotheque.xml.storage.SphereListXMLPart;
import net.fichotheque.xml.storage.SphereMetadataXMLPart;
import net.fichotheque.xml.storage.ThesaurusMetadataXMLPart;
import net.fichotheque.xml.storage.ThesaurusTreeXMLPart;
import net.mapeadores.util.xml.AppendableXMLWriter;
import net.mapeadores.util.xml.XMLUtils;
import net.fichotheque.junction.Junction;


/**
 * Dans les différentes méthodes, EditOrigin peut être nul, cela doit
 * correspondre aux cas de mise à jour au démarrage suite à un changement de
 * version du XML.
 *
 * @author Vincent Calame
 */
public final class Save {

    private Save() {
    }

    public static void saveAddendaMetadata(StorageDirectory bdfdataDirectory, Addenda addenda, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.addendaMetadata(bdfdataDirectory, addenda.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            AddendaMetadataXMLPart addendaMetadataXMLPart = new AddendaMetadataXMLPart(xmlWriter);
            addendaMetadataXMLPart.appendAddendaMetadata(addenda.getAddendaMetadata());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveAlbumMetadata(StorageDirectory bdfdataDirectory, Album album, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.albumMetadata(bdfdataDirectory, album.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            AlbumMetadataXMLPart albumMetadataXMLPart = new AlbumMetadataXMLPart(xmlWriter);
            albumMetadataXMLPart.appendAlbumMetadata(album.getAlbumMetadata());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveFichothequeMetadata(StorageDirectory bdfdataDirectory, FichothequeMetadata fichothequeMetadata, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.fichothequeMetadata(bdfdataDirectory);
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            FichothequeMetadataXMLPart fichothequeMetadataXMLPart = new FichothequeMetadataXMLPart(xmlWriter);
            fichothequeMetadataXMLPart.appendFichothequeMetadata(fichothequeMetadata);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveCorpusMetadata(StorageDirectory bdfdataDirectory, Corpus corpus, EditOrigin editOrigin) {
        SubsetKey masterSubsetKey = null;
        Subset masterSubset = corpus.getMasterSubset();
        if (masterSubset != null) {
            masterSubsetKey = masterSubset.getSubsetKey();
        }
        StorageFile storageFile = BdfdataStorageFileCatalog.corpusMetadata(bdfdataDirectory, corpus.getSubsetKey(), masterSubsetKey);
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            CorpusMetadataXMLPart corpusMetadataXMLPart = new CorpusMetadataXMLPart(xmlWriter);
            corpusMetadataXMLPart.appendCorpusMetadata(corpus.getCorpusMetadata());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveSphereMetadata(StorageDirectory bdfdataDirectory, Sphere sphere, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.sphereMetadata(bdfdataDirectory, sphere.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            SphereMetadataXMLPart sphereMetadataXMLPart = new SphereMetadataXMLPart(xmlWriter);
            sphereMetadataXMLPart.appendSphereMetadata(sphere.getSphereMetadata());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveSphereList(StorageDirectory bdfdataDirectory, Sphere sphere, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.sphereList(bdfdataDirectory, sphere.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            SphereListXMLPart sphereMetadataXMLPart = new SphereListXMLPart(xmlWriter);
            sphereMetadataXMLPart.appendSphereList(sphere, null);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveThesaurusMetadata(StorageDirectory bdfdataDirectory, Thesaurus thesaurus, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.thesaurusMetadata(bdfdataDirectory, thesaurus.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            ThesaurusMetadataXMLPart thesaurusMetadataXMLPart = new ThesaurusMetadataXMLPart(xmlWriter);
            thesaurusMetadataXMLPart.appendThesaurusMetadata(thesaurus.getThesaurusMetadata());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveThesaurusTree(StorageDirectory bdfdataDirectory, Thesaurus thesaurus, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.thesaurusTree(bdfdataDirectory, thesaurus.getSubsetKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            ThesaurusTreeXMLPart thesaurusTreeXMLPart = new ThesaurusTreeXMLPart(xmlWriter);
            thesaurusTreeXMLPart.appendThesaurus(thesaurus, null);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveMotcle(StorageDirectory bdfdataDirectory, Motcle motcle, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.motcle(bdfdataDirectory, motcle.getSubsetKey(), motcle.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            MotcleStorageXMLPart motcleStorageXMLPart = new MotcleStorageXMLPart(xmlWriter);
            motcleStorageXMLPart.appendMotcle(motcle);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveFiche(StorageDirectory bdfdataDirectory, FicheMeta ficheMeta, FicheAPI fiche, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.fiche(bdfdataDirectory, ficheMeta.getSubsetKey(), ficheMeta.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            FicheStorageXMLPart ficheStorageXMLPart = new FicheStorageXMLPart(xmlWriter);
            ficheStorageXMLPart.appendFiche(fiche);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveChrono(StorageDirectory bdfdataDirectory, FicheMeta ficheMeta, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.ficheChrono(bdfdataDirectory, ficheMeta.getSubsetKey(), ficheMeta.getId());
        try (BufferedWriter buf = storageFile.getWriter()) {
            StorageUtils.writeChrono(buf, ficheMeta);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveAttributes(StorageDirectory bdfdataDirectory, FicheMeta ficheMeta, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.ficheAttributes(bdfdataDirectory, ficheMeta.getSubsetKey(), ficheMeta.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            AttributesStorageXMLPart attributesStorageXMLPart = new AttributesStorageXMLPart(xmlWriter);
            attributesStorageXMLPart.appendAttributes(ficheMeta.getAttributes());
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveDocument(StorageDirectory bdfdataDirectory, Document document, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.document(bdfdataDirectory, document.getSubsetKey(), document.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            DocumentStorageXMLPart documentStorageXMLPart = new DocumentStorageXMLPart(xmlWriter);
            documentStorageXMLPart.appendDocument(document);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveIllustration(StorageDirectory bdfdataDirectory, Illustration illustration, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.illustration(bdfdataDirectory, illustration.getSubsetKey(), illustration.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            IllustrationStorageXMLPart documentStorageXMLPart = new IllustrationStorageXMLPart(xmlWriter);
            documentStorageXMLPart.appendIllustration(illustration);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveRedacteur(StorageDirectory bdfdataDirectory, Redacteur redacteur, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.redacteur(bdfdataDirectory, redacteur.getSubsetKey(), redacteur.getId());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            RedacteurStorageXMLPart redacteurStorageXMLPart = new RedacteurStorageXMLPart(xmlWriter);
            redacteurStorageXMLPart.appendRedacteur(redacteur);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveBdfUserPrefs(StorageDirectory bdfdataDirectory, Redacteur redacteur, BdfUserPrefs bdfUserPrefs) {
        StorageFile storageFile = BdfUserDirectory.getPrefsStorageFile(bdfdataDirectory, redacteur.getSubsetKey(), redacteur.getId());
        try (BufferedWriter buf = storageFile.getWriter()) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            BdfUserPrefsXMLPart bdfUserPrefsXMLPart = new BdfUserPrefsXMLPart(xmlWriter);
            bdfUserPrefsXMLPart.addPrefs(bdfUserPrefs);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    public static void saveJunction(StorageDirectory bdfdataDirectory, Junction junction, EditOrigin editOrigin) {
        StorageFile storageFile = BdfdataStorageFileCatalog.junction(bdfdataDirectory, junction.getJunctionKey());
        try (BufferedWriter buf = storageFile.archiveAndGetWriter(editOrigin)) {
            AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf);
            xmlWriter.appendXMLDeclaration();
            JunctionStorageXMLPart junctionStorageXMLPart = new JunctionStorageXMLPart(xmlWriter);
            junctionStorageXMLPart.appendJunction(junction);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

}
