package bamboo.task;

import bamboo.core.*;
import bamboo.crawl.*;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.PosixFileAttributes;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ImportJob {
	private Config config;
	final Crawls crawls;
	final long crawlId;

	private HeritrixJob heritrixJob;
	private List<Path> launches;

	public ImportJob(Config config, Crawls crawls, long crawlId) {
		this.config = config;
		this.crawls = crawls;
		this.crawlId = crawlId;
	}
	
	public void run()  {
		Crawl crawl = crawls.get(crawlId);
		if (crawl.getState() != Crawl.IMPORTING) {
			return; // sanity check
		}
		if (crawl.getCrawlSeriesId() == null)
			throw new RuntimeException("TODO: implement imports without a series");

		try {
			heritrixJob = HeritrixJob.byName(config.getHeritrixJobs(), crawl.getName());
			heritrixJob.checkSuitableForArchiving();

			Path dest = crawls.allocateCrawlPath(crawlId);

			crawls.addWarcs(crawlId, heritrixJob.warcs().collect(Collectors.toList()));

			constructCrawlBundle(heritrixJob.dir(), dest);

			crawls.updateState(crawlId, Crawl.ARCHIVED);

		} catch (IOException e) {
			crawls.updateState(crawlId, Crawl.IMPORT_FAILED);
			throw new UncheckedIOException(e);
		}
	}

	private static boolean shouldIncludeInCrawlBundle(Path path) {
		return !path.getParent().getFileName().toString().equals("warcs") &&
				Files.isRegularFile(path);
	}

	private void constructCrawlBundle(Path src, Path dest) throws IOException {
		Path zipFile = dest.resolve("crawl-bundle.zip");
		try (ZipOutputStream zip = new ZipOutputStream(Files.newOutputStream(zipFile))) {
			Files.walk(src)
					.filter(ImportJob::shouldIncludeInCrawlBundle)
					.forEachOrdered((path) -> {
						ZipEntry entry = new ZipEntry(src.relativize(path).toString());
						try {
							PosixFileAttributes attr = Files.readAttributes(path, PosixFileAttributes.class);
							entry.setCreationTime(attr.creationTime());
							entry.setLastModifiedTime(attr.lastModifiedTime());
							entry.setLastAccessTime(attr.lastAccessTime());
							entry.setSize(attr.size());
							zip.putNextEntry(entry);
							Files.copy(path, zip);
						} catch (IOException e) {
							throw new UncheckedIOException(e);
						}
					});
		}
	}
}

@@ -59,16 +59,73 @@
 crawl.*;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -534,16 +534,93 @@
 rtJob %7B%0A
+%09private static final Logger log = LoggerFactory.getLogger(ImportJob.class);%0A
 %09private
@@ -1146,16 +1146,88 @@
 %09%09try %7B%0A
+%09%09%09log.info(%22Importing crawl id %22 + crawlId + %22 %22 + heritrixJob.dir());%0A
 %09%09%09herit
@@ -1392,16 +1392,66 @@
 rawlId);
+%0A%09%09%09constructCrawlBundle(heritrixJob.dir(), dest);
 %0A%0A%09%09%09cra
@@ -1527,108 +1527,136 @@
 ));%0A
-%0A%09%09%09constructCrawlBundle(heritrixJob.dir(), dest);%0A%0A%09%09%09crawls.updateState(crawlId, Crawl.ARCHIVED);%0A
+%09%09%09crawls.updateState(crawlId, Crawl.ARCHIVED);%0A%09%09%09log.info(%22Import complete of crawl id %22 + crawlId + %22 %22 + heritrixJob.dir());
 %0A%09%09%7D
@@ -1655,34 +1655,32 @@
 ());%0A%09%09%7D catch (
-IO
 Exception e) %7B%0A%09
@@ -1738,39 +1738,83 @@
 %0A%09%09%09
-throw new UncheckedIOException(
+log.error(%22Error importing crawl id %22 + crawlId + %22 %22 + heritrixJob.dir(), 
 e);%0A

Add logging for import jobs