/**
 * Copyright 2000-present Liferay, Inc.
 *
 * Licensed 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.
 */

package com.liferay.blade.samples.integration.test.utils;

import aQute.bnd.osgi.Domain;
import aQute.bnd.version.Version;

import aQute.lib.io.IO;

import com.liferay.portal.kernel.util.StringUtil;

import java.io.File;
import java.io.InputStream;

import java.net.URL;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.FileUtils;

import org.junit.Assert;

/**
 * @author Lawrence Lee
 */
public class BladeCLIUtil {

	public static File bladeJar;

	public static File createProject(
			File testDir, String templateName, String bundleName,
			String...createArgs)
		throws Exception {

		String[] executeArgs = new String[createArgs.length + 6];

		executeArgs[0] = "create";
		executeArgs[1] = "-d";
		executeArgs[2] = testDir.getPath();
		executeArgs[3] = "-t";
		executeArgs[4] = templateName;
		System.arraycopy(createArgs, 0, executeArgs, 5, createArgs.length);
		executeArgs[createArgs.length + 5] = bundleName;

		execute(executeArgs);

		File projectPath = new File(testDir + "/" + bundleName);

		return projectPath;
	}

	public static String execute(File workingDir, String... bladeArgs)
		throws Exception {

		String bladeCLIJarPath = getLatestBladeCLIJar();

		List<String> command = new ArrayList<>();

		command.add("java");
		command.add("-jar");
		command.add(bladeCLIJarPath);

		for (String arg : bladeArgs) {
			command.add(arg);
		}

		Process process = new ProcessBuilder(
			command.toArray(new String[0])).directory(workingDir).start();

		process.waitFor();

		InputStream stream = process.getInputStream();

		String output = new String(IO.read(stream));

		InputStream errorStream = process.getErrorStream();

		List<String> errorList = new ArrayList<>();

		String stringStream = null;

		if (errorStream != null) {
			stringStream = new String(IO.read(errorStream));

			errorList.add(stringStream);
		}

		List<String> filteredErrorList = new ArrayList<>();

		for (String string : errorList) {
			String exclusion = "(.*setlocale.*)";

			Pattern p = Pattern.compile(exclusion, Pattern.DOTALL);

			Matcher m = p.matcher(string);

			while (m.find()) {
				filteredErrorList.add(string);
			}

			if (string.contains("Picked up JAVA_TOOL_OPTIONS:")) {
				filteredErrorList.add(string);
			}
		}

		errorList.removeAll(filteredErrorList);

		Assert.assertTrue(errorList.toString(), errorList.size() <= 1);

		if (errorList.size() == 1) {
			Assert.assertTrue(errorList.get(0), errorList.get(0).isEmpty());
		}

		output = StringUtil.toLowerCase(output);

		return output;
	}

	public static String execute(String... bladeArgs) throws Exception {
		return execute(null, bladeArgs);
	}

	public static String getLatestBladeCLIJar() throws Exception {
		if (bladeJar == null) {
			URL url = new URL(System.getProperty("bladeURL"));
			File file = new File("blade.jar");

			FileUtils.copyURLToFile(url, file);

			Domain jar = Domain.domain(file);

			int bundleVersion = new Version(jar.getBundleVersion()).getMajor();

			if (bundleVersion != 2) {
				throw new Exception(
					"Expecting bladejar with major version 2, found version: " +
						bundleVersion);
			}

			bladeJar = file;
		}

		return bladeJar.getCanonicalPath();
	}

	public static String installBundle(File file) throws Exception {
		String printFileName;
		String bundleID;
		String output;

		if (file.getName().endsWith(".war")) {
			printFileName = file.getName();

			printFileName = printFileName.substring(
				0, printFileName.lastIndexOf('.'));

			output = BladeCLIUtil.execute(
				"sh", "install",
				"webbundle:file://" + file +
					"?Web-ContextPath=/" + printFileName);

			bundleID = output.substring(
				output.indexOf("bundle id:") + 11,
				output.indexOf("\n", output.indexOf("bundle id:")));
		}

		else {
			output = execute("sh", "install", file.toURI().toASCIIString());

			bundleID = output.substring(
					output.indexOf("bundle id:") + 11,
					output.indexOf("\n", output.indexOf("bundle id:")));
		}

		if (output.contains("Failed") || output.contains("Exception")) {
			throw new Exception(output);
		}

		return bundleID;
	}

	public static String startBundle(String bundleID) throws Exception {
		String output = execute("sh", "start", bundleID);

		if (output.contains("Exception")) {
			throw new Exception(output);
		}

		return output;
	}

	public static void uninstallBundle(String... bundleIDArgs)
		throws Exception {

		String[] executeArgs = new String[bundleIDArgs.length + 2];

		executeArgs[0] = "sh";
		executeArgs[1] = "uninstall";
		System.arraycopy(bundleIDArgs, 0, executeArgs, 2, bundleIDArgs.length);
		execute(executeArgs);
	}

}
@@ -751,59 +751,8 @@
 O;%0A%0A
-import com.liferay.portal.kernel.util.StringUtil;%0A%0A
 impo
@@ -3092,52 +3092,8 @@
 %09%7D%0A%0A
-%09%09output = StringUtil.toLowerCase(output);%0A%0A
 %09%09re
@@ -4539,32 +4539,46 @@
 %7D%0A%0A%09%09if (output.
+toLowerCase().
 contains(%22Failed
@@ -4571,17 +4571,17 @@
 ntains(%22
-F
+f
 ailed%22) 
@@ -4586,24 +4586,38 @@
 ) %7C%7C output.
+toLowerCase().
 contains(%22Ex
@@ -4606,33 +4606,33 @@
 ase().contains(%22
-E
+e
 xception%22)) %7B%0A%09%09
@@ -4825,16 +4825,30 @@
 (output.
+toLowerCase().
 contains

make exception handling case insensitive