package biz.aQute.launcher;

import static org.junit.Assert.assertTrue;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;

import org.junit.Test;

import aQute.bnd.build.Run;
import aQute.bnd.build.Workspace;
import aQute.bnd.osgi.Jar;
import aQute.lib.io.IO;

public class LauncherTest {
	File						base					= new File("").getAbsoluteFile();

	private static final String GENERATED_PACKAGED_JAR = "generated/packaged.jar";

	/**
	 * Testing the embedded launcher is quite tricky. This test uses a prefabricated
	 * packaged jar. Notice that you need to reexport that jar for every change in
	 * the launcher since it embeds the launcher. This jar is run twice to see if
	 * the second run will not reinstall the bundles.
	 */

	@Test
	public void testPackaged() throws Exception {
		File file = buildPackage();

		System.setProperty("test.cmd", "quit.no.exit");
		File fwdir = IO.getFile(base, "generated/keepfw");
		IO.delete(fwdir);

		assertTrue(file.isFile());

		String result = runFramework(file);
		assertTrue(result.contains("installing jar/demo.jar"));

		result = runFramework(file);
		assertTrue(result.contains("not updating jar/demo.jar because identical digest"));

	}

	private File buildPackage() throws Exception, IOException {
		Workspace ws = Workspace.getWorkspace(base.getParentFile());
		Run run = Run.createRun(ws, IO.getFile(base, "keep.bndrun"));

		File file = IO.getFile(base, GENERATED_PACKAGED_JAR);
		try (Jar pack = run.pack(null)) {
			assertTrue(ws.check());
			assertTrue(run.check());
			pack.write(file);
		}
		return file;
	}

	private String runFramework(File file) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
			InvocationTargetException, IOException, MalformedURLException {
		PrintStream out = System.err;
		ByteArrayOutputStream bout = new ByteArrayOutputStream();
		PrintStream out2 = new PrintStream(bout);
		System.setErr(out2);

		try (URLClassLoader l = new URLClassLoader(new URL[] {
				file.toURI().toURL()
		}, null)) {
			Class< ? > launcher = l.loadClass("aQute.launcher.pre.EmbeddedLauncher");
			Method main = launcher.getDeclaredMethod("main", String[].class);
			main.invoke(null, (Object) new String[] {});
		}

		out2.flush();
		System.setErr(out);

		return new String(bout.toByteArray(), StandardCharsets.UTF_8);
	}
}

@@ -2187,17 +2187,25 @@
 (out2);%0A
-%0A
+%09%09try %7B%0A%09
 %09%09try (U
@@ -2253,16 +2253,17 @@
 URL%5B%5D %7B%0A
+%09
 %09%09%09%09file
@@ -2281,16 +2281,17 @@
 URL()%0A%09%09
+%09
 %7D, null)
@@ -2294,16 +2294,17 @@
 ull)) %7B%0A
+%09
 %09%09%09Class
@@ -2375,16 +2375,17 @@
 r%22);%0A%09%09%09
+%09
 Method m
@@ -2442,16 +2442,17 @@
 class);%0A
+%09
 %09%09%09main.
@@ -2493,19 +2493,21 @@
  %7B%7D);%0A%09%09
+%09
 %7D%0A%0A
+%09
 %09%09out2.f
@@ -2514,16 +2514,31 @@
 lush();%0A
+%09%09%7D finally %7B%0A%09
 %09%09System
@@ -2550,16 +2550,20 @@
 rr(out);
+%0A%09%09%7D
 %0A%0A%09%09retu

Make sure to always restore System.err