/* FichothequeLib_Tools - Copyright (c) 2013-2022 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 net.fichotheque.tools.parsers.junction;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import net.fichotheque.ExistingNameException;
import net.fichotheque.FichothequeEditor;
import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.AddendaEditor;
import net.fichotheque.addenda.Document;
import net.fichotheque.tools.parsers.DocumentChangeInfo;
import net.fichotheque.utils.AddendaUtils;
import net.mapeadores.util.exceptions.NestedIOException;
import net.mapeadores.util.exceptions.ShouldNotOccurException;
import net.mapeadores.util.text.FileName;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
class DocumentChangeToken {

    private final Addenda addenda;
    private final int id;
    private final DocumentChangeInfo documentChangeInfo;

    DocumentChangeToken(Addenda addenda, int id, DocumentChangeInfo documentChangeInfo) {
        this.addenda = addenda;
        this.id = id;
        this.documentChangeInfo = documentChangeInfo;
    }

    static DocumentChangeToken parse(String tokenString, Addenda addenda) {
        int idx = tokenString.indexOf(':');
        if (idx == -1) {
            return null;
        }
        int documentid;
        try {
            documentid = Integer.parseInt(tokenString.substring(0, idx));
        } catch (NumberFormatException nfe) {
            return null;
        }
        DocumentChangeInfo documentChangeInfo = DocumentChangeInfo.parse(tokenString.substring(idx + 1));
        return new DocumentChangeToken(addenda, documentid, documentChangeInfo);
    }

    void save(FichothequeEditor fichothequeEditor, File tmpDirectory) {
        AddendaEditor addendaEditor = fichothequeEditor.getAddendaEditor(addenda);
        if (addendaEditor == null) {
            return;
        }
        Document document = (Document) addenda.getSubsetItemById(id);
        if (document == null) {
            return;
        }
        String newBasename = documentChangeInfo.getNewBasename();
        if (newBasename != null) {
            newBasename = AddendaUtils.checkBasename(newBasename, addenda);
            try {
                addendaEditor.setBasename(document, newBasename);
            } catch (ExistingNameException | ParseException e) {
                throw new ShouldNotOccurException("Check done before");
            }
        }
        int tmpFileNameCount = documentChangeInfo.getTmpFileCount();
        for (int i = 0; i < tmpFileNameCount; i++) {
            FileName tmpFileName = documentChangeInfo.getTmpFileName(i);
            String extension = tmpFileName.getExtension();
            if (extension == null) {
                continue;
            }
            File f = DocumentChangeToken.toTmpFile(tmpDirectory, tmpFileName.toString());
            if (f == null) {
                continue;
            }
            updateVersion(addendaEditor, document, f, extension);
        }
        int removedExtensionCount = documentChangeInfo.getRemovedExtensionCount();
        for (int i = 0; i < removedExtensionCount; i++) {
            String extension = documentChangeInfo.getRemovedExtension(i);
            addendaEditor.removeVersion(document, extension);
        }
    }

    static File toTmpFile(File tmpDirectory, String tmpFileName) {
        tmpFileName = StringUtils.normalizeRelativePath(tmpFileName);
        if (tmpFileName == null) {
            return null;
        }
        File f = new File(tmpDirectory, tmpFileName);
        if (!f.exists()) {
            return null;
        }
        if (f.isDirectory()) {
            return null;
        }
        return f;
    }

    static void updateVersion(AddendaEditor addendaEditor, Document document, File f, String extension) {
        try (FileInputStream is = new FileInputStream(f)) {
            addendaEditor.saveVersion(document, extension, is);
        } catch (ParseException e) {
            throw new ShouldNotOccurException("Check done before");
        } catch (IOException ioe) {
            throw new NestedIOException(ioe);
        }
    }

}
