package org.apache.taverna.robundle.manifest;

/*
 * 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.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.taverna.robundle.Bundle;
import org.apache.taverna.robundle.Bundles;
import org.junit.Test;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestManifestJSON {
	
	@Test
	public void testHistory () throws IOException
	{
		Path tmpBundle = Files.createTempFile ("testbundle", "history");

		// create history
		try (Bundle bundle = Bundles.createBundle())
		{
			Bundles.closeAndSaveBundle (bundle, tmpBundle);
		}
		catch (IOException e)
		{
			fail ("failed to create bundle for history test: " + e.getMessage ());
		}
		
		// make sure it doesn't fail if there is no history
		try (Bundle bundle = Bundles.openBundle (tmpBundle))
		{
			Manifest manifest = bundle.getManifest();
			Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
			assertFalse ("did not expect a history file", Files.exists (evolutionPath));
			assertEquals ("did not expect a history", 0, manifest.getHistory ().size ());
			
			Files.createDirectories(evolutionPath.getParent());
			Bundles.setStringValue(
					evolutionPath,
					"<manifest.json> < http://purl.org/pav/retrievedFrom> "
							+ "<http://wf4ever.github.io/ro/bundle/2013-05-21/example/.ro/manifest.json> .");
			manifest.getHistory().add(evolutionPath);
			assertTrue ("expected a history file", Files.exists (evolutionPath));
			assertTrue ("expected a history", manifest.getHistory ().size () > 0);
			
			Bundles.closeBundle (bundle);
		}
		catch (IOException e)
		{
			fail ("failed to read bundle for history test: " + e.getMessage ());
		}
		
		// check if history is still there
		try (Bundle bundle = Bundles.openBundleReadOnly (tmpBundle))
		{
			Manifest manifest = bundle.getManifest();
			Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
			assertTrue ("expected a history file", Files.exists (evolutionPath));
			assertEquals ("expected exactly one history", 1, manifest.getHistory ().size ());
			Bundles.closeBundle (bundle);
		}
		catch (IOException e)
		{
			fail ("failed to read bundle for history test: " + e.getMessage ());
		}
		
		Files.delete (tmpBundle);
	}
	
	@Test
	public void createBundle() throws Exception {
		// Create bundle as in Example 3 of the specification
		// http://wf4ever.github.io/ro/bundle/2013-05-21/
		try (Bundle bundle = Bundles.createBundle()) {
			Calendar createdOnCal = Calendar.getInstance(
					TimeZone.getTimeZone("Z"), Locale.ENGLISH);
			// "2013-03-05T17:29:03Z"
			// Remember months are 0-based in java.util.Calendar!
			createdOnCal.set(2013, 3 - 1, 5, 17, 29, 03);
			createdOnCal.set(Calendar.MILLISECOND, 0);
			FileTime createdOn = FileTime.fromMillis(createdOnCal
					.getTimeInMillis());
			Manifest manifest = bundle.getManifest();
			manifest.setCreatedOn(createdOn);
			Agent createdBy = new Agent("Alice W. Land");
			createdBy.setUri(URI.create("http://example.com/foaf#alice"));
			createdBy.setOrcid(URI
					.create("http://orcid.org/0000-0002-1825-0097"));

			manifest.setCreatedBy(createdBy);

			Path evolutionPath = bundle.getPath(".ro/evolution.ttl");
			Files.createDirectories(evolutionPath.getParent());
			Bundles.setStringValue(
					evolutionPath,
					"<manifest.json> < http://purl.org/pav/retrievedFrom> "
							+ "<http://wf4ever.github.io/ro/bundle/2013-05-21/example/.ro/manifest.json> .");
			manifest.getHistory().add(evolutionPath);

			Path jpeg = bundle.getPath("folder/soup.jpeg");
			Files.createDirectory(jpeg.getParent());
			Files.createFile(jpeg);
			// register in manifest first
			bundle.getManifest().getAggregation(jpeg);

			URI blog = URI.create("http://example.com/blog/");
			bundle.getManifest().getAggregation(blog);

			Path readme = bundle.getPath("README.txt");
			Files.createFile(readme);
			PathMetadata readmeMeta = bundle.getManifest().getAggregation(
					readme);
			readmeMeta.setMediatype("text/plain");
			Agent readmeCreatedby = new Agent("Bob Builder");
			readmeCreatedby.setUri(URI.create("http://example.com/foaf#bob"));
			readmeMeta.setCreatedBy(readmeCreatedby);

			// 2013-02-12T19:37:32.939Z
			createdOnCal.set(2013, 2 - 1, 12, 19, 37, 32);
			createdOnCal.set(Calendar.MILLISECOND, 939);
			createdOn = FileTime.fromMillis(createdOnCal.getTimeInMillis());
			Files.setLastModifiedTime(readme, createdOn);
			readmeMeta.setCreatedOn(createdOn);

			PathMetadata comments = bundle.getManifest().getAggregation(
					URI.create("http://example.com/comments.txt"));
			comments.getOrCreateBundledAs()
					.setURI(URI
							.create("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644"));
			comments.getOrCreateBundledAs().setFolder(
					bundle.getPath("/folder/"));
			comments.getOrCreateBundledAs().setFilename("external.txt");

			PathAnnotation jpegAnn = new PathAnnotation();
			jpegAnn.setAbout(jpeg);
			Path soupProps = Bundles.getAnnotations(bundle).resolve(
					"soup-properties.ttl");
			Bundles.setStringValue(soupProps,
					"</folder/soup.jpeg> <http://xmlns.com/foaf/0.1/depicts> "
							+ "<http://example.com/menu/tomato-soup> .");
			jpegAnn.setContent(soupProps);
			// jpegAnn.setContent(URI.create("annotations/soup-properties.ttl"));
			jpegAnn.setUri(URI
					.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"));
			manifest.getAnnotations().add(jpegAnn);

			PathAnnotation proxyAnn = new PathAnnotation();
			proxyAnn.setAbout(comments.getBundledAs().getURI());
			proxyAnn.setContent(URI
					.create("http://example.com/blog/they-aggregated-our-file"));
			manifest.getAnnotations().add(proxyAnn);

			Path metaAnn = Bundles.getAnnotations(bundle).resolve(
					"a-meta-annotation-in-this-ro.txt");
			Bundles.setStringValue(metaAnn,
					"This bundle contains an annotation about /folder/soup.jpeg");

			PathAnnotation metaAnnotation = new PathAnnotation();
			metaAnnotation.setAbout(bundle.getRoot());
			metaAnnotation
					.getAboutList()
					.add(URI.create("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf"));

			metaAnnotation.setContent(metaAnn);
			manifest.getAnnotations().add(metaAnnotation);

			Path jsonPath = bundle.getManifest().writeAsJsonLD();
			ObjectMapper objectMapper = new ObjectMapper();
			String jsonStr = Bundles.getStringValue(jsonPath);
			//System.out.println(jsonStr);
			JsonNode json = objectMapper.readTree(jsonStr);
			checkManifestJson(json);
		}
	}

	public void checkManifestJson(JsonNode json) {
		JsonNode context = json.get("@context");
		assertNotNull("Could not find @context", context);
		assertTrue("@context SHOULD be an array", context.isArray());
		assertTrue("@context SHOULD include a context", context.size() > 0);
		JsonNode lastContext = context.get(context.size() - 1);
		assertEquals(
				"@context SHOULD include https://w3id.org/bundle/context as last item",
				"https://w3id.org/bundle/context", lastContext.asText());

		assertEquals("/", json.get("id").asText());

		JsonNode manifest = json.get("manifest");
		if (manifest.isValueNode()) {
			assertEquals(
					"manifest SHOULD be literal value \"manifest.json\" or list",
					"manifest.json", manifest.asText());
		} else {
			assertTrue("manifest is neither literal or list",
					manifest.isArray());
			boolean found = false;
			for (JsonNode n : manifest) {
				found = n.asText().equals("manifest.json");
				if (found) {
					break;
				}
			}
			;
			assertTrue("Could not find 'manifest.json' in 'manifest' list: "
					+ manifest, found);
		}

		assertEquals("2013-03-05T17:29:03Z", json.get("createdOn").asText());
		JsonNode createdBy = json.get("createdBy");
		assertNotNull("Could not find createdBy", createdBy);
		assertEquals("http://example.com/foaf#alice", createdBy.get("uri")
				.asText());
		assertEquals("http://orcid.org/0000-0002-1825-0097",
				createdBy.get("orcid").asText());
		assertEquals("Alice W. Land", createdBy.get("name").asText());

		JsonNode history = json.get("history");
		if (history.isValueNode()) {
			assertEquals("evolution.ttl", history.asText());
		} else {
			assertEquals("evolution.ttl", history.get(0).asText());
		}

		JsonNode aggregates = json.get("aggregates");
		assertTrue("aggregates not a list", aggregates.isArray());
		JsonNode soup = aggregates.get(0);
		if (soup.isValueNode()) {
			assertEquals("/folder/soup.jpeg", soup.asText());
		} else {
			assertEquals("/folder/soup.jpeg", soup.get("uri").asText());
		}

		JsonNode blog = aggregates.get(1);
		if (blog.isValueNode()) {
			assertEquals("http://example.com/blog/", blog.asText());
		} else {
			assertEquals("http://example.com/blog/", blog.get("uri").asText());
		}

		JsonNode readme = aggregates.get(2);
		assertEquals("/README.txt", readme.get("uri").asText());
		assertEquals("text/plain", readme.get("mediatype").asText());
		assertEquals("2013-02-12T19:37:32.939Z", readme.get("createdOn")
				.asText());
		JsonNode readmeCreatedBy = readme.get("createdBy");
		assertEquals("http://example.com/foaf#bob", readmeCreatedBy.get("uri")
				.asText());
		assertEquals("Bob Builder", readmeCreatedBy.get("name").asText());

		JsonNode comments = aggregates.get(3);
		assertEquals("http://example.com/comments.txt", comments.get("uri")
				.asText());
		JsonNode bundledAs = comments.get("bundledAs");
		assertEquals("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644", bundledAs
				.get("uri").asText());
		assertEquals("/folder/", bundledAs.get("folder").asText());
		assertEquals("external.txt", bundledAs.get("filename").asText());

		JsonNode annotations = json.get("annotations");
		assertTrue("annotations MUST be a list", annotations.isArray());

		JsonNode ann0 = annotations.get(0);
		assertEquals("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf",
				ann0.get("uri").asText());
		assertEquals("/folder/soup.jpeg", ann0.get("about").asText());
		assertEquals("annotations/soup-properties.ttl", ann0.get("content")
				.asText());

		JsonNode ann1 = annotations.get(1);
		assertNull(ann1.get("annotation"));
		assertEquals("urn:uuid:a0cf8616-bee4-4a71-b21e-c60e6499a644",
				ann1.get("about").asText());
		assertEquals("http://example.com/blog/they-aggregated-our-file", ann1
				.get("content").asText());

		JsonNode ann2 = annotations.get(2);
		assertNull(ann2.get("annotation"));
		JsonNode about = ann2.get("about");
		assertTrue("about was not a list", about.isArray());
		assertEquals("/", about.get(0).asText());
		assertEquals("urn:uuid:d67466b4-3aeb-4855-8203-90febe71abdf", about
				.get(1).asText());
		assertEquals("annotations/a-meta-annotation-in-this-ro.txt",
				ann2.get("content").asText());

	}

	@Test
	public void checkJsonFromSpec() throws Exception {
		// Verify that our test confirms the existing spec example
		ObjectMapper objectMapper = new ObjectMapper();
		JsonNode json = objectMapper.readTree(getClass().getResource(
				"/manifest.json"));
		checkManifestJson(json);

	}
}
