package org.apache.taverna.databundle;
/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/


import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.file.DirectoryStream;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;

import org.apache.taverna.databundle.DataBundles.ResolveOptions;
import org.apache.taverna.robundle.Bundle;
import org.apache.taverna.scufl2.api.container.WorkflowBundle;
import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

//import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;


public class TestDataBundles {
	private Bundle dataBundle;

    protected void checkSignature(Path zip) throws IOException {
		String MEDIATYPE = "application/vnd.wf4ever.robundle+zip";
		/*
		 * Check position 30++ according to RO Bundle specification
		 * http://purl.org/wf4ever/ro-bundle#ucf
		 */
		byte[] expected = ("mimetype" + MEDIATYPE + "PK").getBytes("ASCII");

		try (InputStream in = Files.newInputStream(zip)) {
			byte[] signature = new byte[expected.length];
			int MIME_OFFSET = 30;
			assertEquals(MIME_OFFSET, in.skip(MIME_OFFSET));
			assertEquals(expected.length, in.read(signature));
			assertArrayEquals(expected, signature);
		}
	}
	
	@Before
	public void createDataBundle() throws IOException {
	    dataBundle = DataBundles.createBundle();
	}
	
	@After
	public void closeDataBundle() throws IOException {
	    dataBundle.close();
	}
	
	@Test
    public void clear() throws Exception {        
        Path inputs = DataBundles.getInputs(dataBundle);
        Path file1 = inputs.resolve("file1");
        Path file1Txt = inputs.resolve("file1.txt");
        Path file1Png = inputs.resolve("file1.png");
        Path file1Else = inputs.resolve("file1somethingelse.txt");
        
        Files.createFile(file1);
        Files.createFile(file1Txt);
        Files.createFile(file1Png);
        Files.createFile(file1Else); 
        
        DataBundles.deleteAllExtensions(file1);
        
        assertFalse(Files.exists(file1));
        assertFalse(Files.exists(file1Txt));
        assertFalse(Files.exists(file1Png));
        assertTrue(Files.exists(file1Else));
	}

	   
    @Test
    public void clearRecursive() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path file1 = inputs.resolve("file1");
        Path file1Dir = inputs.resolve("file1.dir");
        
        Files.createDirectory(file1);
        Files.createDirectory(file1Dir);
        Path nested = file1Dir.resolve("nested");
        Files.createDirectory(nested);
        
        
        Path filePng = file1Dir.resolve("file.png");
        Path fileTxt = nested.resolve("file1somethingelse.txt");
        
        Files.createFile(filePng);
        Files.createFile(fileTxt); 
        
        DataBundles.deleteAllExtensions(file1);
        
        assertFalse(Files.exists(file1));
        assertFalse(Files.exists(nested));
        assertFalse(Files.exists(file1Dir));
        assertFalse(Files.exists(filePng));
        assertFalse(Files.exists(fileTxt));
    }

	
	@Test
	public void createList() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		assertTrue(Files.isDirectory(list));
	}
	
	@Test
	public void getError() throws Exception {	
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		DataBundles.setError(portIn1, "Something did not work", "A very\n long\n error\n trace");		
		
		ErrorDocument error = DataBundles.getError(portIn1);
		assertTrue(error.getCausedBy().isEmpty());
		
		assertEquals("Something did not work", error.getMessage());
		// Notice that the lack of trailing \n is preserved 
		assertEquals("A very\n long\n error\n trace", error.getTrace());	
		
		assertEquals(null, DataBundles.getError(null));
	}

	@Test
	public void getErrorCause() throws Exception {		
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		Path cause1 = DataBundles.setError(portIn1, "Something did not work", "A very\n long\n error\n trace");
		Path portIn2 = DataBundles.getPort(inputs, "in2");
		Path cause2 = DataBundles.setError(portIn2, "Something else did not work", "Shorter trace");
		
		
		Path outputs = DataBundles.getOutputs(dataBundle);
		Path portOut1 = DataBundles.getPort(outputs, "out1");
		DataBundles.setError(portOut1, "Errors in input", "", cause1, cause2);

		ErrorDocument error = DataBundles.getError(portOut1);
		assertEquals("Errors in input", error.getMessage());
		assertEquals("", error.getTrace());
		assertEquals(2, error.getCausedBy().size());
		
		assertTrue(Files.isSameFile(cause1, error.getCausedBy().get(0)));
		assertTrue(Files.isSameFile(cause2, error.getCausedBy().get(1)));
	}

	@Test
	public void getInputs() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		assertTrue(Files.isDirectory(inputs));
		// Second time should not fail because it alreadresolvy exists
		inputs = DataBundles.getInputs(dataBundle);
		assertTrue(Files.isDirectory(inputs));
		assertEquals(dataBundle.getRoot(), inputs.getParent());
	}

	@Test
	public void getList() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		for (int i = 0; i < 5; i++) {
			Path item = DataBundles.newListItem(list);
			DataBundles.setStringValue(item, "test" + i);
		}
		List<Path> paths = DataBundles.getList(list);
		assertEquals(5, paths.size());
		assertEquals("test0", DataBundles.getStringValue(paths.get(0)));
		assertEquals("test4", DataBundles.getStringValue(paths.get(4)));
		
		assertEquals(null, DataBundles.getList(null));
	}

	@Test
	public void getListItem() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		for (int i = 0; i < 5; i++) {
			Path item = DataBundles.newListItem(list);
			DataBundles.setStringValue(item, "item " + i);
		}
		// set at next available position
		Path item5 = DataBundles.getListItem(list, 5);
		assertTrue(item5.getFileName().toString().contains("5"));
		DataBundles.setStringValue(item5, "item 5");
	
		
		// set somewhere later
		Path item8 = DataBundles.getListItem(list, 8);
		assertTrue(item8.getFileName().toString().contains("8"));
		DataBundles.setStringValue(item8, "item 8");
		
		Path item7 = DataBundles.getListItem(list, 7);
		assertFalse(Files.exists(item7));
		assertFalse(DataBundles.isList(item7));
		assertFalse(DataBundles.isError(item7));
		assertFalse(DataBundles.isValue(item7));
		// TODO: Is it really missing? item1337 is also missing..
		assertTrue(DataBundles.isMissing(item7));
		
		
		// overwrite #2
		Path item2 = DataBundles.getListItem(list, 2);		
		DataBundles.setStringValue(item2, "replaced");
		
		
		List<Path> listItems = DataBundles.getList(list);
		assertEquals(9, listItems.size());
		assertEquals("item 0", DataBundles.getStringValue(listItems.get(0)));
		assertEquals("item 1", DataBundles.getStringValue(listItems.get(1)));
		assertEquals("replaced", DataBundles.getStringValue(listItems.get(2)));
		assertEquals("item 3", DataBundles.getStringValue(listItems.get(3)));
		assertEquals("item 4", DataBundles.getStringValue(listItems.get(4)));
		assertEquals("item 5", DataBundles.getStringValue(listItems.get(5)));
		assertNull(listItems.get(6));
		assertNull(listItems.get(7));
		assertEquals("item 8", DataBundles.getStringValue(listItems.get(8)));
		
	}

    @Test
    public void getListSize() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path list = DataBundles.getPort(inputs, "in1");
        DataBundles.createList(list);
        for (int i = 0; i < 5; i++) {
            Path item = DataBundles.newListItem(list);
            DataBundles.setStringValue(item, "item " + i);
        }
        assertEquals(5, DataBundles.getListSize(list));

        // set at next available position
        Path item5 = DataBundles.getListItem(list, 5);
        assertTrue(item5.getFileName().toString().contains("5"));
        DataBundles.setStringValue(item5, "item 5");
        assertEquals(6, DataBundles.getListSize(list));

        // set somewhere beyond the end
        Path item8 = DataBundles.getListItem(list, 8);
        assertTrue(item8.getFileName().toString().contains("8"));
        DataBundles.setStringValue(item8, "item 8");
        assertEquals(9, DataBundles.getListSize(list));
        
        // Evil test - very high number
        long highNumber = 3l * Integer.MAX_VALUE;
        Path itemHigh = DataBundles.getListItem(list, highNumber);
        assertTrue(itemHigh.getFileName().toString().contains(Long.toString(highNumber)));
        DataBundles.setStringValue(itemHigh, "item 6442450941");
        assertEquals(highNumber+1l, DataBundles.getListSize(list));
    }
	
	@Test
    public void getListItemChecksExtension() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path portIn1 = DataBundles.getPort(inputs, "in1");
        Path list = DataBundles.newListItem(portIn1);
        
        Path item = DataBundles.newListItem(list);
        
        Path ref = DataBundles.setReference(item, URI.create("http://example.com/"));
        Path itemAgain = DataBundles.getListItem(list, 0);
        assertEquals(ref, itemAgain);
        assertFalse(itemAgain.equals(portIn1));
        assertTrue(Files.exists(itemAgain));
    }

	@Test
	public void getOutputs() throws Exception {
		Path outputs = DataBundles.getOutputs(dataBundle);
		assertTrue(Files.isDirectory(outputs));
		// Second time should not fail because it already exists
		outputs = DataBundles.getOutputs(dataBundle);
		assertTrue(Files.isDirectory(outputs));
		assertEquals(dataBundle.getRoot(), outputs.getParent());
	}
	
	@Test
	public void getPort() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		assertFalse(Files.exists(portIn1));
		assertEquals(inputs, portIn1.getParent());
	}

	@Test
    public void getPortChecksExtension() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path portIn1 = DataBundles.getPort(inputs, "in1");
        assertFalse(Files.exists(portIn1));
        Path ref = DataBundles.setReference(portIn1, URI.create("http://example.com/"));
        Path portIn1Again = DataBundles.getPort(inputs, "in1");
        assertEquals(ref, portIn1Again);
        assertFalse(portIn1Again.equals(portIn1));
        assertTrue(Files.exists(portIn1Again));
    }

	@Test
	public void getPorts() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		DataBundles.createList(DataBundles.getPort(inputs, "in1"));
		DataBundles.createList(DataBundles.getPort(inputs, "in2"));
		DataBundles.setStringValue(DataBundles.getPort(inputs, "value"),
				"A value");
		Map<String, Path> ports = DataBundles.getPorts(DataBundles
				.getInputs(dataBundle));
		assertEquals(3, ports.size());
//		System.out.println(ports);
		assertTrue(ports.containsKey("in1"));
		assertTrue(ports.containsKey("in2"));
		assertTrue(ports.containsKey("value"));

		assertEquals("A value", DataBundles.getStringValue(ports.get("value")));

	}

	@Test
	public void hasInputs() throws Exception {
		assertFalse(DataBundles.hasInputs(dataBundle));
		DataBundles.getInputs(dataBundle); // create on demand
		assertTrue(DataBundles.hasInputs(dataBundle));
	}

	@Test
	public void hasOutputs() throws Exception {
		assertFalse(DataBundles.hasOutputs(dataBundle));
		DataBundles.getInputs(dataBundle); // independent
		assertFalse(DataBundles.hasOutputs(dataBundle));
		DataBundles.getOutputs(dataBundle); // create on demand
		assertTrue(DataBundles.hasOutputs(dataBundle));
	}

	@Test
	public void isError() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		DataBundles.setError(portIn1, "Something did not work", "A very\n long\n error\n trace");		
		
		assertFalse(DataBundles.isList(portIn1));		
		assertFalse(DataBundles.isValue(portIn1));
		assertFalse(DataBundles.isMissing(portIn1));
		assertFalse(DataBundles.isReference(portIn1));
		assertTrue(DataBundles.isError(portIn1));		
	}

	@Test
	public void isList() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		assertTrue(DataBundles.isList(list));
		assertFalse(DataBundles.isValue(list));
		assertFalse(DataBundles.isError(list));
		assertFalse(DataBundles.isReference(list));
		assertFalse(DataBundles.isMissing(list));
	}
	
	@Test
	public void isMissing() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		
		assertFalse(DataBundles.isList(portIn1));		
		assertFalse(DataBundles.isValue(portIn1));
		assertFalse(DataBundles.isError(portIn1));
		assertTrue(DataBundles.isMissing(portIn1));
		assertFalse(DataBundles.isReference(portIn1));
	}

	@Test
    public void isValueOnError() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        DataBundles.setError(DataBundles.getPort(inputs, "test"),
                "error", "");
        assertFalse(DataBundles.isValue(DataBundles.getPorts(inputs).get("test")));
    }
	
	@Test
    public void isValueOnReference() throws Exception {
	    Path inputs = DataBundles.getInputs(dataBundle);
	    DataBundles.setReference(DataBundles.getPort(inputs, "test"), URI.create("http://www.example.com/"));
	    assertFalse(DataBundles.isValue(DataBundles.getPorts(inputs).get("test")));
    }
	
	@Test
	public void listOfLists() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		Path sublist0 = DataBundles.newListItem(list);
		DataBundles.createList(sublist0);
		
		Path sublist1 = DataBundles.newListItem(list);
		DataBundles.createList(sublist1);
		
		assertEquals(Arrays.asList("0/", "1/"), ls(list));
		
		DataBundles.setStringValue(DataBundles.newListItem(sublist1), 
				"Hello");
		
		assertEquals(Arrays.asList("0"), ls(sublist1));
		
		assertEquals("Hello",DataBundles.getStringValue( 
				DataBundles.getListItem(DataBundles.getListItem(list, 1), 0)));
	}

	
	
	protected List<String> ls(Path path) throws IOException {
		List<String> paths = new ArrayList<>();
		try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
			for (Path p : ds) {
				paths.add(p.getFileName() + "");
			}
		}
		Collections.sort(paths);
		return paths;
	}
	
	@Test(expected=FileAlreadyExistsException.class)
    public void newListAlreadyExistsAsError() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path list = DataBundles.getPort(inputs, "in1");
        Path err = DataBundles.setError(list, "a", "b");
        assertFalse(Files.isRegularFile(list));
        assertFalse(Files.isDirectory(list));
        assertTrue(Files.isRegularFile(err));                
        DataBundles.createList(list);
    }
	
	@Test(expected=FileAlreadyExistsException.class)
    public void newListAlreadyExistsAsFile() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path list = DataBundles.getPort(inputs, "in1");
        DataBundles.setStringValue(list, "A string");
        assertTrue(Files.isRegularFile(list));
        assertFalse(Files.isDirectory(list));
        DataBundles.createList(list);
    }
	

    @Test(expected=FileAlreadyExistsException.class)
    public void newListAlreadyExistsAsReference() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path list = DataBundles.getPort(inputs, "in1");
        Path ref = DataBundles.setReference(list, URI.create("http://example.com/"));
        assertFalse(Files.isRegularFile(list));
        assertFalse(Files.isDirectory(list));
        assertTrue(Files.isRegularFile(ref));                
        DataBundles.createList(list);
    }
    
    @Test
	public void newListItem() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		Path item0 = DataBundles.newListItem(list);
		assertEquals(list, item0.getParent());
		assertTrue(item0.getFileName().toString().contains("0"));
		assertFalse(Files.exists(item0));
		DataBundles.setStringValue(item0, "test");

		Path item1 = DataBundles.newListItem(list);
		assertTrue(item1.getFileName().toString().contains("1"));
		// Because we've not actually created item1 yet
		assertEquals(item1, DataBundles.newListItem(list));
		DataBundles.setStringValue(item1, "test");

		// Check that DataBundles.newListItem can deal with gaps
		Files.delete(item0);
		Path item2 = DataBundles.newListItem(list);
		assertTrue(item2.getFileName().toString().contains("2"));

		// Check that non-numbers don't interfere
		Path nonumber = list.resolve("nonumber");
		Files.createFile(nonumber);
		item2 = DataBundles.newListItem(list);
		assertTrue(item2.getFileName().toString().contains("2"));

		// Check that extension is stripped
		Path five = list.resolve("5.txt");
		Files.createFile(five);
		Path item6 = DataBundles.newListItem(list);
		assertTrue(item6.getFileName().toString().contains("6"));
	}
    
    @Test
    public void resolveString() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		DataBundles.setStringValue(DataBundles.newListItem(list), "test0");
		// 1 http:// reference
		URI reference = URI.create("http://example.com/");
		DataBundles.setReference(DataBundles.newListItem(list), reference);
		// 2 file:/// reference
		Path tmpFile = Files.createTempFile("test", ".txt");
		URI fileRef = tmpFile.toUri();
		assertEquals("file", fileRef.getScheme());
		DataBundles.setReference(DataBundles.newListItem(list), fileRef);
		// 3 empty (null)
		// 4 error
		DataBundles.setError(DataBundles.getListItem(list,  4), "Example error", "1. Tried it\n2. Didn't work");
		
		
		
		
		Object resolved = DataBundles.resolve(list, ResolveOptions.STRING);
		assertTrue("Didn't resolve to a list", resolved instanceof List);
		
		List resolvedList = (List) resolved;
		assertEquals("Unexpected list size", 5, resolvedList.size());
		
		assertTrue(resolvedList.get(0) instanceof String);
		assertEquals("test0", resolvedList.get(0));
		
		assertTrue(resolvedList.get(1) instanceof URL);
		assertEquals(reference, ((URL)resolvedList.get(1)).toURI());
		
		assertTrue(resolvedList.get(2) instanceof File);
		assertEquals(tmpFile.toFile(), resolvedList.get(2));
		
		assertNull(resolvedList.get(3));
		assertTrue(resolvedList.get(4) instanceof ErrorDocument);
		assertEquals("Example error", ((ErrorDocument)resolvedList.get(4)).getMessage());
		
    }    

    @Test
    public void resolveNestedString() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		
		
		Path nested0 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested0);		
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,0");
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,1");
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,2");
		Path nested1 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested1); // empty
		Path nested2 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested2);
		DataBundles.setStringValue(DataBundles.newListItem(nested2), "test2,0");
		
		
		
		List<List<String>> resolved = (List<List<String>>) DataBundles.resolve(list, ResolveOptions.STRING);
		
		assertEquals("Unexpected list size", 3, resolved.size());
		assertEquals("Unexpected sublist[0] size", 3, resolved.get(0).size());
		assertEquals("Unexpected sublist[1] size", 0, resolved.get(1).size());
		assertEquals("Unexpected sublist[2] size", 1, resolved.get(2).size());

		
		assertEquals("test0,0", resolved.get(0).get(0));
		assertEquals("test0,1", resolved.get(0).get(1));
		assertEquals("test0,2", resolved.get(0).get(2));
		assertEquals("test2,0", resolved.get(2).get(0));		
    }        


    @Test
    public void resolveStream() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		
		Path nested0 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested0);		
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,0");
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,1");
		DataBundles.setStringValue(DataBundles.newListItem(nested0), "test0,2");
		DataBundles.setError(DataBundles.newListItem(nested0), "Ignore me", "This error is hidden");
		Path nested1 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested1); // empty
		Path nested2 = DataBundles.newListItem(list);
		DataBundles.newListItem(nested2);
		DataBundles.setStringValue(DataBundles.newListItem(nested2), "test2,0");
		DataBundles.setReference(DataBundles.newListItem(nested2), URI.create("http://example.com/"));
		
		

		assertEquals(6, DataBundles.resolveAsStream(list, Object.class).count());		
		assertEquals(6, DataBundles.resolveAsStream(list, Path.class).count());
		assertEquals(5, DataBundles.resolveAsStream(list, URI.class).count());
		assertEquals(1, DataBundles.resolveAsStream(list, URL.class).count());
		assertEquals(0, DataBundles.resolveAsStream(list, File.class).count());
		assertEquals(1, DataBundles.resolveAsStream(list, ErrorDocument.class).count());
		// Let's have a look at one of the types in detail
		assertEquals(4, DataBundles.resolveAsStream(list, String.class).count());		
		Stream<String> resolved = DataBundles.resolveAsStream(list, String.class);
		Object[] strings = resolved.sorted().map(t -> t.replace("test", "X")).toArray();
		// NOTE: We can only assume the below order because we used .sorted()
		assertEquals("X0,0", strings[0]);
		assertEquals("X0,1", strings[1]);
		assertEquals("X0,2", strings[2]);
		assertEquals("X2,0", strings[3]);
    }        
    
    @Test
    public void resolveURIs() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		Path test0 = DataBundles.newListItem(list);
		DataBundles.setStringValue(test0, "test0");
		// 1 http:// reference
		URI reference = URI.create("http://example.com/");
		DataBundles.setReference(DataBundles.newListItem(list), reference);
		// 2 file:/// reference
		Path tmpFile = Files.createTempFile("test", ".txt");
		URI fileRef = tmpFile.toUri();
		assertEquals("file", fileRef.getScheme());
		DataBundles.setReference(DataBundles.newListItem(list), fileRef);
		// 3 empty (null)
		// 4 error
		Path error4 = DataBundles.getListItem(list,  4);
		DataBundles.setError(error4, "Example error", "1. Tried it\n2. Didn't work");
		
		List resolved = (List) DataBundles.resolve(list, ResolveOptions.URI);
		assertEquals(test0.toUri(), resolved.get(0));
		assertEquals(reference, resolved.get(1));
		assertEquals(fileRef, resolved.get(2));
		assertNull(resolved.get(3));
		// NOTE: Need to get the Path again due to different file extension
		assertTrue(resolved.get(4) instanceof ErrorDocument);		
		//assertTrue(DataBundles.getListItem(list,  4).toUri(), resolved.get(4));
    }
    

    @Test
    public void resolvePaths() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		Path test0 = DataBundles.newListItem(list);
		DataBundles.setStringValue(test0, "test0");
		// 1 http:// reference
		URI reference = URI.create("http://example.com/");
		Path test1 = DataBundles.setReference(DataBundles.newListItem(list), reference);
		// 2 file:/// reference
		Path tmpFile = Files.createTempFile("test", ".txt");
		URI fileRef = tmpFile.toUri();
		assertEquals("file", fileRef.getScheme());
		Path test2 = DataBundles.setReference(DataBundles.newListItem(list), fileRef);
		// 3 empty (null)
		// 4 error
		Path error4 = DataBundles.setError(DataBundles.getListItem(list,  4), "Example error", "1. Tried it\n2. Didn't work");
		
		List<Path> resolved = (List<Path>) DataBundles.resolve(list, ResolveOptions.PATH);
		assertEquals(test0, resolved.get(0));
		assertEquals(test1, resolved.get(1));
		assertEquals(test2, resolved.get(2));
		assertNull(resolved.get(3));
		assertEquals(error4, resolved.get(4));		
    }

    @Test
    public void resolveReplaceError() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		DataBundles.setStringValue(DataBundles.newListItem(list), "test0");
		// 1 error
		DataBundles.setError(DataBundles.newListItem(list), 
				"Example error", "1. Tried it\n2. Didn't work");
		
		List resolved = (List) DataBundles.resolve(list, ResolveOptions.STRING, ResolveOptions.REPLACE_ERRORS);
		assertEquals("test0", resolved.get(0));
		assertNull(resolved.get(1));
    }

    @Test
    public void resolveReplaceNull() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		Path test0 = DataBundles.newListItem(list);
		DataBundles.setStringValue(test0, "test0");
		// 1 empty
		// 2 error
		DataBundles.setError(DataBundles.getListItem(list, 2), 
				"Example error", "1. Tried it\n2. Didn't work");
		
		List resolved = (List) DataBundles.resolve(list, ResolveOptions.REPLACE_ERRORS, ResolveOptions.REPLACE_NULL);
		assertEquals(test0, resolved.get(0));
		assertEquals("", resolved.get(1));
		assertEquals("", resolved.get(2));
    }
    

    @Test
    public void resolveDefault() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		DataBundles.createList(list);
		// 0 string value
		Path test0 = DataBundles.newListItem(list);
		DataBundles.setStringValue(test0, "test0");
		// 1 http:// reference
		URI reference = URI.create("http://example.com/");
		Path test1 = DataBundles.setReference(DataBundles.newListItem(list), reference);
		// 2 file:/// reference
		Path tmpFile = Files.createTempFile("test", ".txt");
		URI fileRef = tmpFile.toUri();
		assertEquals("file", fileRef.getScheme());
		Path test2 = DataBundles.setReference(DataBundles.newListItem(list), fileRef);
		// 3 empty (null)
		// 4 error
		Path error4 = DataBundles.setError(DataBundles.getListItem(list,  4), "Example error", "1. Tried it\n2. Didn't work");
		
		List resolved = (List) DataBundles.resolve(list, ResolveOptions.DEFAULT);
		assertEquals(test0, resolved.get(0));
		assertTrue(resolved.get(1) instanceof URL);
		assertEquals("http://example.com/", resolved.get(1).toString());
		assertTrue(resolved.get(2) instanceof File);
		assertEquals(tmpFile.toFile(), resolved.get(2));
		assertNull(resolved.get(3));
		assertTrue(resolved.get(4) instanceof ErrorDocument);
    }
    
    @Test
    public void resolveBinaries() throws Exception {
    	Path inputs = DataBundles.getInputs(dataBundle);
		Path list = DataBundles.getPort(inputs, "in1");
		Path item = DataBundles.newListItem(list);

		byte[] bytes = new byte[] { 
				// Those lovely lower bytes who don't work well in UTF-8
				0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 
				// and some higher ones for fun
				-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17,-18,
				-19,-20,-21,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31
		};
		Files.write(item, bytes);
		
		
		List resolvedBytes = (List)DataBundles.resolve(list, ResolveOptions.BYTES);
		assertArrayEquals(bytes, (byte[])resolvedBytes.get(0));

		List resolvedString = (List)DataBundles.resolve(list, ResolveOptions.STRING);		
		// The below will always fail as several of the above bytes are not parsed as valid UTF-8
		// but instead be substituted with replacement characters. 		
		//assertArrayEquals(bytes, ((String)resolvedString.get(0)).getBytes(StandardCharsets.UTF_8));
    }
    
    @Test
	public void setErrorArgs() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		Path errorPath = DataBundles.setError(portIn1, "Something did not work", "A very\n long\n error\n trace");		
		assertEquals("in1.err", errorPath.getFileName().toString());

		List<String> errLines = Files.readAllLines(errorPath, Charset.forName("UTF-8"));
		assertEquals(6, errLines.size());
		assertEquals("", errLines.get(0));
		assertEquals("Something did not work", errLines.get(1));
		assertEquals("A very", errLines.get(2));
		assertEquals(" long", errLines.get(3));
		assertEquals(" error", errLines.get(4));
		assertEquals(" trace", errLines.get(5));
	}

    @Test
	public void setErrorCause() throws Exception {		
		Path inputs = DataBundles.getInputs(dataBundle);
		Path portIn1 = DataBundles.getPort(inputs, "in1");
		Path cause1 = DataBundles.setError(portIn1, "Something did not work", "A very\n long\n error\n trace");
		Path portIn2 = DataBundles.getPort(inputs, "in2");
		Path cause2 = DataBundles.setError(portIn2, "Something else did not work", "Shorter trace");
		
		
		Path outputs = DataBundles.getOutputs(dataBundle);
		Path portOut1 = DataBundles.getPort(outputs, "out1");
		Path errorPath = DataBundles.setError(portOut1, "Errors in input", "", cause1, cause2);
		
		List<String> errLines = Files.readAllLines(errorPath, Charset.forName("UTF-8"));
		assertEquals("../inputs/in1.err", errLines.get(0));
		assertEquals("../inputs/in2.err", errLines.get(1));
		assertEquals("", errLines.get(2));
	}

    @Test
    public void setErrorExistsAsError() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path err = DataBundles.setError(in1, "a", "b");
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(err));
        DataBundles.setError(in1, "c", "d");
        assertEquals("c", DataBundles.getError(in1).getMessage());
    }

    @Test(expected=FileAlreadyExistsException.class)
    public void setErrorExistsAsList() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path list = DataBundles.getPort(inputs, "in1");
        DataBundles.createList(list);
        assertFalse(Files.isRegularFile(list));
        assertTrue(Files.isDirectory(list));
        DataBundles.setError(list, "a", "b");
    }

	@Test(expected=FileAlreadyExistsException.class)
    public void setErrorExistsAsReference() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path ref = DataBundles.setReference(in1, URI.create("http://example.com/"));
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(ref));
        DataBundles.setError(in1, "a", "b");
    }
	
    @Test(expected=FileAlreadyExistsException.class)
    public void setErrorExistsAsValue() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        DataBundles.setStringValue(in1, "test");
        assertTrue(Files.isRegularFile(in1));
        DataBundles.setError(in1, "a", "b");
    }
	
	@Test
	public void setErrorObj() throws Exception {
		Path inputs = DataBundles.getInputs(dataBundle);

		Path portIn1 = DataBundles.getPort(inputs, "in1");
		Path cause1 = DataBundles.setError(portIn1, "a", "b");
		Path portIn2 = DataBundles.getPort(inputs, "in2");
		Path cause2 = DataBundles.setError(portIn2, "c", "d");
		
		
		Path outputs = DataBundles.getOutputs(dataBundle);
		Path portOut1 = DataBundles.getPort(outputs, "out1");

		ErrorDocument error = new ErrorDocument();
		error.getCausedBy().add(cause1);
		error.getCausedBy().add(cause2);
		
		error.setMessage("Something did not work");
		error.setTrace("Here\nis\nwhy\n");
		
		Path errorPath = DataBundles.setError(portOut1, error);		
		assertEquals("out1.err", errorPath.getFileName().toString());

		List<String> errLines = Files.readAllLines(errorPath, Charset.forName("UTF-8"));
		assertEquals(8, errLines.size());
		assertEquals("../inputs/in1.err", errLines.get(0));
		assertEquals("../inputs/in2.err", errLines.get(1));
		assertEquals("", errLines.get(2));
		assertEquals("Something did not work", errLines.get(3));
		assertEquals("Here", errLines.get(4));
		assertEquals("is", errLines.get(5));
		assertEquals("why", errLines.get(6));
		assertEquals("", errLines.get(7));
	}
	
    @Test(expected = FileAlreadyExistsException.class)
    public void setReferenceExistsAsError() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path err = DataBundles.setError(in1, "a", "b");
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(err));
        DataBundles.setReference(in1, URI.create("http://example.com/"));
    }
	
    @Test(expected = FileAlreadyExistsException.class)
    public void setReferenceExistsAsList() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        DataBundles.createList(in1);
        assertTrue(Files.isDirectory(in1));
        DataBundles.setReference(in1, URI.create("http://example.com/"));
    }

    @Test
    public void setReferenceExistsAsReference() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path ref = DataBundles.setReference(in1, URI.create("http://example.com/"));
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(ref));
        DataBundles.setReference(in1, URI.create("http://example.com/"));
    }
    

    @Test(expected = FileAlreadyExistsException.class)
    public void setReferenceExistsAsValue() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        DataBundles.setStringValue(in1, "Hello");
        assertTrue(Files.isRegularFile(in1));
        DataBundles.setReference(in1, URI.create("http://example.com/"));
    }
    
    @Test(expected=FileAlreadyExistsException.class)
    public void setStringExistsAsError() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path err = DataBundles.setError(in1, "x", "X");
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(err));
        DataBundles.setStringValue(in1, "Hello");
    }

    
    @Test(expected=FileAlreadyExistsException.class)
    public void setStringExistsAsList() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        DataBundles.createList(in1);
        assertTrue(Files.isDirectory(in1));
        DataBundles.setStringValue(in1, "Hello");
    }
    
    

    @Test(expected=FileAlreadyExistsException.class)
    public void setStringExistsAsReference() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        Path ref = DataBundles.setReference(in1, URI.create("http://example.com/"));
        assertFalse(Files.exists(in1));
        assertTrue(Files.isRegularFile(ref));
        DataBundles.setStringValue(in1, "Hello");
    }

    @Test
    public void setStringExistsAsString() throws Exception {
        Path inputs = DataBundles.getInputs(dataBundle);
        Path in1 = DataBundles.getPort(inputs, "in1");
        DataBundles.setStringValue(in1, "A");
        assertTrue(Files.isRegularFile(in1));
        DataBundles.setStringValue(in1, "B");
        assertEquals("B", DataBundles.getStringValue(in1));
    }

    @Test
    public void getIntermediates() throws Exception {
        Path intermediates = DataBundles.getIntermediates(dataBundle);
        assertEquals("/intermediates", intermediates.toString());
        assertTrue(Files.isDirectory(intermediates));
    }

    
    @Test(expected=FileAlreadyExistsException.class)
    public void getIntermediatesFails() throws Exception {
        Path intermediates = DataBundles.getIntermediates(dataBundle);
        Files.delete(intermediates);
        Files.createFile(intermediates);
        DataBundles.getIntermediates(dataBundle);
    }
    
    @Test
    public void getIntermediate() throws Exception {
        UUID uuid = UUID.randomUUID();
        Path inter = DataBundles.getIntermediate(dataBundle, uuid);
        assertFalse(Files.exists(inter));
        DataBundles.setStringValue(inter, "intermediate");
        Path parent = inter.getParent();
        assertEquals(dataBundle.getRoot().resolve("intermediates"), parent.getParent());
        String parentName = parent.getFileName().toString();
        assertEquals(2, parentName.length());
        assertTrue(uuid.toString().startsWith(parentName));
        // Filename is a valid string
        String interFileName = inter.getFileName().toString();
        assertTrue(interFileName.startsWith(parentName));
        assertEquals(uuid, UUID.fromString(interFileName));
    }
    
    @Test
    public void getWorkflow() throws Exception {
        Path wf = DataBundles.getWorkflow(dataBundle);
        assertEquals("/workflow", wf.toString());
    }

    @Test
    public void setWorkflowBundle() throws Exception {
        WorkflowBundleIO wfBundleIO = new WorkflowBundleIO();
        WorkflowBundle wfBundle = wfBundleIO.createBundle();
        DataBundles.setWorkflowBundle(dataBundle, wfBundle);
        
        Path wf = DataBundles.getWorkflow(dataBundle);
        assertEquals("/workflow.wfbundle", wf.toString());        
        assertEquals("application/vnd.taverna.scufl2.workflow-bundle", 
                Files.probeContentType(wf));
    }

    // TODO: Why was this ignored? Check with taverna-language-0.15.x RC emails
    @Ignore
    @Test
    public void getWorkflowBundle() throws Exception {
        WorkflowBundleIO wfBundleIO = new WorkflowBundleIO();
        WorkflowBundle wfBundle = wfBundleIO.createBundle();
        
        String name = wfBundle.getName();
        String wfName = wfBundle.getMainWorkflow().getName();
        URI id = wfBundle.getIdentifier();
        
        DataBundles.setWorkflowBundle(dataBundle, wfBundle);

        // Reload the bundle
        wfBundle = DataBundles.getWorkflowBundle(dataBundle);        
        assertEquals(name, wfBundle.getName());
        assertEquals(wfName, wfBundle.getMainWorkflow().getName());        
        assertEquals(id, wfBundle.getIdentifier());        
    }

    @Test
    public void getWorkflowReport() throws Exception {
        Path runReport = DataBundles.getWorkflowRunReport(dataBundle);
        assertEquals("/workflowrun.json", runReport.toString());
    }
    
    @Test
    public void getWorkflowReportAsJson() throws Exception {        
        Path runReport = DataBundles.getWorkflowRunReport(dataBundle);
        DataBundles.setStringValue(runReport, "{ \"valid\": \"not really\", \"number\": 1337 }");
        JsonNode json = DataBundles.getWorkflowRunReportAsJson(dataBundle);
        assertEquals("not really", json.path("valid").asText());
        assertEquals(1337, json.path("number").asInt());
    }
    
    @Test
    public void setWorkflowReport() throws Exception {
        ObjectNode report = JsonNodeFactory.instance.objectNode();
        report.put("number", 1337);
        DataBundles.setWorkflowRunReport(dataBundle, report);
        Path runReport = DataBundles.getWorkflowRunReport(dataBundle);
        String json = DataBundles.getStringValue(runReport);
        assertTrue(json.contains("number"));
        assertTrue(json.contains("1337"));
    }
    

}

