package jj.resource;

import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jj.JJStartup;

class AssetResourcePreloader implements JJStartup {
	
	private final Logger log = LoggerFactory.getLogger(AssetResourcePreloader.class);
	
	private final ResourceFinder finder;
	
	AssetResourcePreloader(final ResourceFinder finder) {
		this.finder = finder;
	}

	@Override
	public void start() throws Exception {
		
		log.info("preloading internal assets");

		if (AssetResourceCreator.basePath != null) {
			doWalk(AssetResourceCreator.basePath);
		} else if (AssetResourceCreator.myJar != null) {
			try (FileSystem myJarFS = FileSystems.newFileSystem(AssetResourceCreator.myJar, null)) {
				doWalk(myJarFS.getPath("/jj/assets"));
			}
		}
		
		
		log.debug("preload complete");
	}
	
	private void doWalk(final Path path) throws Exception {
		Files.walkFileTree(path, new FileVisitor<Path>() {

			@Override
			public FileVisitResult preVisitDirectory(Path dir,
					BasicFileAttributes attrs) throws IOException {
				return FileVisitResult.CONTINUE;
			}

			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				String baseName = path.relativize(file).toString();
				finder.loadResource(AssetResource.class, baseName);
				return FileVisitResult.CONTINUE;
			}

			@Override
			public FileVisitResult visitFileFailed(Path file, IOException exc)
					throws IOException {
				throw exc;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc)
					throws IOException {
				if (exc != null) throw exc;
				return FileVisitResult.CONTINUE;
			}
		});
	}
}

@@ -348,16 +348,61 @@
 ctory;%0A%0A
+import jj.JJExecutors;%0Aimport jj.JJRunnable;%0A
 import j
@@ -594,16 +594,56 @@
 nder;%0A%09%0A
+%09private final JJExecutors executors;%0A%09%0A
 %09AssetRe
@@ -689,94 +689,297 @@
 nder
-) %7B%0A%09%09this.finder = finder;%0A%09%7D%0A%0A%09@Override%0A%09public void start() throws Exception %7B%0A%09%09%0A
+, final JJExecutors executors) %7B%0A%09%09this.finder = finder;%0A%09%09this.executors = executors;%0A%09%7D%0A%0A%09@Override%0A%09public void start() throws Exception %7B%0A%09%09%0A%09%09executors.ioExecutor().submit(new JJRunnable(%22internal asset preloader%22) %7B%0A%09%09%09%0A%09%09%09@Override%0A%09%09%09protected void innerRun() throws Exception %7B%0A%09%09
 %09%09lo
@@ -1017,16 +1017,18 @@
 ets%22);%0A%0A
+%09%09
 %09%09if (As
@@ -1066,16 +1066,18 @@
 null) %7B%0A
+%09%09
 %09%09%09doWal
@@ -1110,16 +1110,18 @@
 ePath);%0A
+%09%09
 %09%09%7D else
@@ -1163,16 +1163,18 @@
 null) %7B%0A
+%09%09
 %09%09%09try (
@@ -1257,24 +1257,26 @@
 ull)) %7B%0A%09%09%09%09
+%09
+%09
 doWalk(myJar
@@ -1309,20 +1309,30 @@
 %0A%09%09%09
+%09%09
 %7D%0A%09%09
+%09
+%09
 %7D%0A%09%09
+%09
+%09%0A%09%09%09%09
 %0A%09%09
-%0A
 %09%09lo
@@ -1360,16 +1360,35 @@
 lete%22);%0A
+%09%09%09%09%0A%09%09%09%7D%0A%09%09%7D);%0A%09%09%0A
 %09%7D%0A%09%0A%09pr

switch into the i/o thread to preload