package org.purl.wf4ever.robundle;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.jena.riot.RiotException;
import org.purl.wf4ever.robundle.fs.BundleFileSystem;
import org.purl.wf4ever.robundle.manifest.Manifest;
import org.purl.wf4ever.robundle.manifest.RDFToManifest;
import org.purl.wf4ever.robundle.manifest.odf.ODFManifest;

public class Bundle implements Closeable {

    private boolean deleteOnClose;
    private final Path root;
    private Manifest manifest;

    public Bundle(Path root, boolean deleteOnClose) {
        this.root = root;
        this.setDeleteOnClose(deleteOnClose);
    }

    @Override
    public void close() throws IOException {
        close(isDeleteOnClose());
    }

    protected void close(boolean deleteOnClose) throws IOException {
        if (! getFileSystem().isOpen()) {
            return;

        }
        // update manifest
        getManifest().populateFromBundle();
        getManifest().writeAsJsonLD();
        if (ODFManifest.containsManifest(this)) {
        	getManifest().writeAsManifestXML();
        }
        
        
        getFileSystem().close();
        if (deleteOnClose) {
            Files.deleteIfExists(getSource());
        }
    }

    public FileSystem getFileSystem() {
        return getRoot().getFileSystem();
    }

    public Path getPath(String path) {
		return getRoot().resolve(path);
	}
    
    public Path getRoot() {
        return root;
    }

    public Path getSource() {
        BundleFileSystem fs = (BundleFileSystem) getFileSystem();
        return fs.getSource();
    }

    public boolean isDeleteOnClose() {
        return deleteOnClose;
    }

    public void setDeleteOnClose(boolean deleteOnClose) {
        this.deleteOnClose = deleteOnClose;
    }

    public Manifest getManifest() throws IOException {
        if (manifest == null) {
            synchronized(this) {
                if (manifest == null) {
                    manifest = readOrPopulateManifest();
                }
            }
        }
        return manifest;
    }

    protected Manifest readOrPopulateManifest() throws IOException {
        Manifest newManifest = new Manifest(this);                    
        Path manifestPath = Bundles.getManifestPath(this);        
        if (Files.exists(manifestPath)) { 
            try (InputStream manifestStream = Files.newInputStream(manifestPath)) { 
                new RDFToManifest().readTo(manifestStream, newManifest, manifestPath.toUri());                
            }
            // TODO: Also support reading manifest.rdf?        
        } else if (ODFManifest.containsManifest(this) ){
        	new ODFManifest(newManifest).readManifestXML();        	
        } else {
            // Fallback (might be a fresh or 3rd party bundle), populate from zip content
            newManifest.populateFromBundle();
        }
        return newManifest;
    }

	


}

@@ -204,51 +204,8 @@
 h;%0A%0A
-import org.apache.jena.riot.RiotException;%0A
 impo
@@ -355,32 +355,99 @@
 .RDFToManifest;%0A
+import org.purl.wf4ever.robundle.manifest.combine.CombineManifest;%0A
 import org.purl.
@@ -994,17 +994,16 @@
 return;%0A
-%0A
         
@@ -996,32 +996,77 @@
 turn;%0A        %7D%0A
+%0A        if (! deleteOnClose) %7B%09           %0A%09
         // updat
@@ -1076,16 +1076,17 @@
 anifest%0A
+%09
         
@@ -1113,32 +1113,33 @@
 teFromBundle();%0A
+%09
         getManif
@@ -1157,24 +1157,25 @@
 AsJsonLD();%0A
+%09
         if (
@@ -1208,24 +1208,25 @@
 st(this)) %7B%0A
+%09
         %09get
@@ -1243,24 +1243,27 @@
 .writeAs
+ODF
 Manifest
 XML();%0A 
@@ -1258,15 +1258,129 @@
 fest
-XML
+();%0A%09        %7D%0A%09        if (CombineManifest.containsManifest(this)) %7B%0A%09        %09getManifest().writeAsCombineManifest
 ();%0A
+%09
     
@@ -1385,32 +1385,40 @@
       %7D%0A        
+%7D else %7B
 %0A        %0A      
@@ -1402,32 +1402,231 @@
  else %7B%0A        
+%09// FIXME: Enable this if closing temporary bundles is %0A        %09// slow doing closing (as those files are being compressed):%0A        %09//RecursiveDeleteVisitor.deleteRecursively(getRoot());%0A        %7D
 %0A        getFile
@@ -3209,25 +3209,137 @@
 stXML();
-        %09
+%0A        %7D else if (CombineManifest.containsManifest(this))%7B%0A        %09new CombineManifest(newManifest).readManifestXML();
 %0A       

Write Combine Manifest if exists