package modules.admin.ControlPanel.actions;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.UUID;

import javax.tools.JavaFileObject;

import org.skyve.content.MimeType;
import org.skyve.domain.messages.DomainException;
import org.skyve.metadata.controller.DownloadAction;
import org.skyve.util.FileUtil;
import org.skyve.util.RuntimeCompiler;
import org.skyve.util.Util;
import org.skyve.web.WebContext;

import modules.admin.ControlPanel.ControlPanelExtension;

public class DownloadSAIL extends DownloadAction<ControlPanelExtension> {
	private static final long serialVersionUID = 6509370665603777126L;

	@Override
	public void prepare(ControlPanelExtension bean, WebContext webContext)
	throws Exception {
		ExecuteSAIL.executeSAIL(bean);
	}
	
	@Override
	public Download download(ControlPanelExtension bean, WebContext webContext)
	throws Exception {
		String sailSource = sailSource(bean.getUnescapedResults(), bean.getSailBaseUrl());
		bean.setResults(null);
		JavaFileObject java = RuntimeCompiler.javaSource("Sail", sailSource);
		
		Download result = null;
		File outputFolder = null;
		try {
			String outputFolderPath = RuntimeCompiler.COMPILE_PATH + UUID.randomUUID().toString();
			outputFolder = new File(outputFolderPath);
			outputFolder.mkdirs();
			if (RuntimeCompiler.compile(java,
											outputFolderPath,
											RuntimeCompiler.COMPILE_PATH + "junit-4.12.jar",
											RuntimeCompiler.COMPILE_PATH + "skyve-core.jar",
											RuntimeCompiler.COMPILE_PATH + "test.jar")) {
				ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
				FileUtil.createJarArchive(outputFolder, out);
				return new Download("sail.jar", new ByteArrayInputStream(out.toByteArray()), MimeType.gzip);
			}
			throw new DomainException("Something went wrong. The compiler returned a false.");
		}
		catch (Exception e) {
			String msg = e.getLocalizedMessage();
			if (msg == null) {
				msg = "Something went wrong. The compiler threw a " + e.getClass();
			}
			msg = sailSource + '\n' + msg;
			result = new Download("sail.txt", new ByteArrayInputStream(msg.getBytes(Util.UTF8)), MimeType.plain);
		}
		finally {
			if (outputFolder != null) {
				FileUtil.delete(outputFolder);
			}
		}
		return result;
	}
	
	static String sailSource(String methods, String baseUrl) {
		StringBuilder result = new StringBuilder(2048);

		result.append("import util.sail.BrowserConfiguration;\n");
		result.append("import util.sail.Devices;\n");
		result.append("import util.sail.PrimeFacesTest;\n\n");
		result.append("import org.junit.After;\n");
		result.append("import org.junit.Before;\n");
		result.append("import org.junit.Test;\n\n");
		result.append("public class Sail extends PrimeFacesTest {\n");
		result.append("\t@Before\n");
		result.append("\tpublic void setup() throws Exception {\n");
		result.append("\t\tsetupChrome(new BrowserConfiguration().baseUrl(\"").append(baseUrl).append("\").pathToDriver(\"").append(((File.pathSeparatorChar == ':') ? "./chromedriver" : "./chromedriver.exe")).append("\").userAgentString(Devices.ipad.userAgentString));\n");
		result.append("\t}\n\n");
		result.append("\t@After\n");
		result.append("\tpublic void teardown() {\n");
		result.append("\t\ttearDownBrowser();\n");
		result.append("\t}\n");
		result.append(methods);
		result.append("}\n");
		return result.toString();
	}
}

@@ -2064,12 +2064,12 @@
 e + 
-'%5Cn'
+%22%5Cn%22
  + m
@@ -2401,16 +2401,201 @@
 2048);%0A%0A
+%09%09result.append(%22import java.io.File;%5Cn%5Cn%22);%0A%09%09result.append(%22import org.junit.After;%5Cn%22);%0A%09%09result.append(%22import org.junit.Before;%5Cn%22);%0A%09%09result.append(%22import org.junit.Test;%5Cn%5Cn%22);%0A
 %09%09result
@@ -2756,148 +2756,8 @@
 %22);%0A
-%09%09result.append(%22import org.junit.After;%5Cn%22);%0A%09%09result.append(%22import org.junit.Before;%5Cn%22);%0A%09%09result.append(%22import org.junit.Test;%5Cn%5Cn%22);%0A
 %09%09re
@@ -3030,21 +3030,8 @@
 ver(
-%5C%22%22).append((
 (Fil
@@ -3060,16 +3060,17 @@
  ':') ? 
+%5C
 %22./chrom
@@ -3080,12 +3080,14 @@
 iver
+%5C
 %22 : 
+%5C
 %22./c
@@ -3105,20 +3105,8 @@
 .exe
-%22)).append(%22
 %5C%22).

Fix Sail test class generation to be cross platform.