package org.purl.wf4ever.robundle.manifest;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.junit.Test;
import org.purl.wf4ever.robundle.Bundle;
import org.purl.wf4ever.robundle.Bundles;

public class TestManifest {
    @Test
    public void populateFromBundle() throws Exception {
        Bundle bundle = exampleBundle();

        Path r = bundle.getRoot();
        URI base = r.toUri();

        Manifest manifest = new Manifest(bundle);
        manifest.populateFromBundle();

        List<String> uris = new ArrayList<>();
        for (PathMetadata s : manifest.getAggregates()) {
            uris.add(s.getFile().toASCIIString());
            Path path = uri2path(base, s.getFile());
            assertNotNull(path.getParent());
            assertEquals(Manifest.withSlash(path.getParent()), s.getFolder());
            if (s.getFile().equals(URI.create("f/nested/empty/"))) {
                continue;
                // Folder's don't need proxy and createdOn
            }            
            assertEquals("urn", s.getProxy().getScheme());
            UUID.fromString(s.getProxy().getSchemeSpecificPart().replace("uuid:", ""));
            assertEquals(s.getCreatedOn(), Files.getLastModifiedTime(path));
        }
        assertFalse(uris.contains("mimetype"));
        assertFalse(uris.contains("META-INF"));
        assertTrue(uris.remove("hello.txt"));
        assertTrue(uris.remove("f/file1.txt"));
        assertTrue(uris.remove("f/file2.txt"));
        assertTrue(uris.remove("f/file3.txt"));
        assertTrue(uris.remove("f/nested/file1.txt"));
        assertTrue(uris.remove("f/nested/empty/"));
        assertTrue(uris.isEmpty());
    }

    private Path uri2path(URI base, URI uri) {
        URI fileUri = base.resolve(uri);
        return Paths.get(fileUri);
    }


    @Test
    public void writeAsJsonLD() throws Exception {
        Bundle bundle = exampleBundle();
        Manifest manifest = new Manifest(bundle);
        manifest.populateFromBundle();
        Path jsonld = manifest.writeAsJsonLD();
        assertEquals(bundle.getFileSystem().getPath(".ro",  "manifest.json"), jsonld);
        assertTrue(Files.exists(jsonld));
        System.out.write(Files.readAllBytes(jsonld));
    }
    
    protected Bundle exampleBundle() throws IOException {
        Path source;
        try (Bundle bundle = Bundles.createBundle()) {
            source = bundle.getSource();
            Path r = bundle.getRoot();
            Files.createFile(r.resolve("hello.txt"));
            Path f = r.resolve("f");
            Files.createDirectory(f);
            Files.createFile(f.resolve("file3.txt"));
            Files.createFile(f.resolve("file2.txt"));
            Files.createFile(f.resolve("file1.txt"));

            Path nested = f.resolve("nested");
            Files.createDirectory(nested);
            Files.createFile(nested.resolve("file1.txt"));

            Files.createDirectory(nested.resolve("empty"));
            bundle.setDeleteOnClose(false);
        }
        return Bundles.openBundle(source);
    }
}

@@ -2344,223 +2344,1156 @@
 Path
- jsonld = manifest.writeAsJsonLD();%0A        assertEquals(bundle.getFileSystem().getPath(%22.ro%22,  %22manifest.json%22), jsonld);%0A        assertTrue(Files.exists(jsonld));%0A        System.out.write(Files.readAllBytes(jsonld
+Metadata helloMeta = null;%0A        for (PathMetadata meta : manifest.getAggregates()) %7B%0A            URI root = URI.create(%22/%22);%0A            if (root.resolve(meta.getFile()).equals(root.resolve(%22hello.txt%22))) %7B%0A                helloMeta = meta;%0A            %7D%0A        %7D%0A        assertNotNull(%22No metadata for %3C/hello.txt%3E%22, helloMeta);%0A        %0A        %0A        %0A        Path jsonld = manifest.writeAsJsonLD();%0A        assertEquals(bundle.getFileSystem().getPath(%22.ro%22,  %22manifest.json%22), jsonld);%0A        assertTrue(Files.exists(jsonld));%0A        String manifestStr = new String(Files.readAllBytes(jsonld), %22UTF8%22);%0A        System.out.println(manifestStr);%0A        %0A        // Rough and ready that somethings are there%0A        // TODO: Read back and check as JSON structure%0A        // TODO: Check as JSON-LD graph %0A        assertTrue(manifestStr.contains(%22@context%22));%0A        assertTrue(manifestStr.contains(%22http://purl.org/wf4ever/ro-bundle/context.json%22));%0A        assertTrue(manifestStr.contains(%22f/file2.txt%22));%0A        assertTrue(manifestStr.contains(%22hello.txt%22));%0A        assertTrue(manifestStr.contains(helloMeta.getProxy().toASCIIString()
 ));%0A

test json output of manifest