// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you 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 org.apache.juneau.utils;

import static org.apache.juneau.internal.IOUtils.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.logging.*;

import org.apache.juneau.internal.*;
import org.apache.juneau.utils.IOPipe.*;

/**
 * Utility class for running operating system processes.
 *
 * <p>
 * Similar to {@link java.lang.ProcessBuilder} but with additional features.
 */
public class ProcBuilder {

	private java.lang.ProcessBuilder pb = new java.lang.ProcessBuilder();
	private TeeWriter outWriters = new TeeWriter(), logWriters = new TeeWriter();
	private LineProcessor lp;
	private Process p;
	private int maxExitStatus = 0;
	private boolean byLines;
	private String divider = "--------------------------------------------------------------------------------";

	/**
	 * Creates a process builder with the specified arguments.
	 *
	 * <p>
	 * Equivalent to calling <c>ProcessBuilder.create().command(args);</c>
	 *
	 * @param args The command-line arguments.
	 * @return A new process builder.
	 */
	public static ProcBuilder create(Object...args) {
		return new ProcBuilder().command(args);
	}

	/**
	 * Creates an empty process builder.
	 *
	 * @return A new process builder.
	 */
	public static ProcBuilder create() {
		return new ProcBuilder().command();
	}

	/**
	 * Command arguments.
	 *
	 * <p>
	 * Arguments can be collections or arrays and will be automatically expanded.
	 *
	 * @param args The command-line arguments.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder command(Object...args) {
		return commandIf(ANY, args);
	}

	/**
	 * Command arguments if the specified matcher matches.
	 *
	 * <p>
	 * Can be used for specifying OS-specific commands.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	ProcBuilder pb = ProcBuilder
	 * 		.create()
	 * 		.commandIf(<jsf>WINDOWS</jsf>, <js>"cmd /c dir"</js>)
	 * 		.commandIf(<jsf>UNIX</jsf>, <js>"bash -c ls"</js>)
	 * 		.merge()
	 * 		.execute();
	 * </p>
	 *
	 * @param m The matcher.
	 * @param args The command line arguments if matcher matches.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder commandIf(Matcher m, Object...args) {
		if (m.matches())
			pb.command(toList(args));
		return this;
	}

	/**
	 * Append to the command arguments.
	 *
	 * <p>
	 * Arguments can be collections or arrays and will be automatically expanded.
	 *
	 * @param args The command-line arguments.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder append(Object...args) {
		return appendIf(ANY, args);
	}

	/**
	 * Append to the command arguments if the specified matcher matches.
	 *
	 * <p>
	 * Arguments can be collections or arrays and will be automatically expanded.
	 *
	 * @param m The matcher.
	 * @param args The command line arguments if matcher matches.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder appendIf(Matcher m, Object...args) {
		if (m.matches())
			pb.command().addAll(toList(args));
		return this;
	}

	/**
	 * Merge STDOUT and STDERR into a single stream.
	 *
	 * @return This object (for method chaining).
	 */
	public ProcBuilder merge() {
		pb.redirectErrorStream(true);
		return this;
	}

	/**
	 * Use by-lines mode.
	 *
	 * <p>
	 * Flushes output after every line of input.
	 *
	 * @return This object (for method chaining).
	 */
	public ProcBuilder byLines() {
		this.byLines = true;
		return this;
	}

	/**
	 * Pipe output to the specified writer.
	 *
	 * <p>
	 * The method can be called multiple times to write to multiple writers.
	 *
	 * @param w The writer to pipe to.
	 * @param close Close the writer afterwards.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder pipeTo(Writer w, boolean close) {
		this.outWriters.add(w, close);
		return this;
	}

	/**
	 * Pipe output to the specified writer, but don't close the writer.
	 *
	 * @param w The writer to pipe to.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder pipeTo(Writer w) {
		return pipeTo(w, false);
	}

	/**
	 * Pipe output to the specified writer, including the command and return code.
	 *
	 * <p>
	 * The method can be called multiple times to write to multiple writers.
	 *
	 * @param w The writer to pipe to.
	 * @param close Close the writer afterwards.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder logTo(Writer w, boolean close) {
		this.logWriters.add(w, close);
		this.outWriters.add(w, close);
		return this;
	}

	/**
	 * Pipe output to the specified writer, including the command and return code.
	 *
	 * <p>
	 * The method can be called multiple times to write to multiple writers.
	 * Don't close the writer afterwards.
	 *
	 * @param w The writer to pipe to.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder logTo(Writer w) {
		return logTo(w, false);
	}

	/**
	 * Pipe output to the specified writer, including the command and return code.
	 * The method can be called multiple times to write to multiple writers.
	 *
	 * @param level The log level.
	 * @param logger The logger to log to.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder logTo(final Level level, final Logger logger) {
		if (logger.isLoggable(level)) {
			logTo(new StringWriter() {
				private boolean isClosed;  // Prevents messages from being written twice.
				@Override /* Writer */
				public void close() {
					if (! isClosed)
						logger.log(level, this.toString());
					isClosed = true;
				}
			}, true);
		}
		return this;
	}

	/**
	 * Line processor to use to process/convert lines of output returned by the process.
	 *
	 * @param lp The new line processor.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder lp(LineProcessor lp) {
		this.lp = lp;
		return this;
	}

	/**
	 * Append the specified environment variables to the process.
	 *
	 * @param env The new set of environment variables.
	 * @return This object (for method chaining).
	 */
	@SuppressWarnings({"rawtypes"})
	public ProcBuilder env(Map env) {
		if (env != null)
			for (Map.Entry e : (Set<Map.Entry>)env.entrySet())
				environment(e.getKey().toString(), e.getValue() == null ? null : e.getValue().toString());
		return this;
	}

	/**
	 * Append the specified environment variable.
	 *
	 * @param key The environment variable name.
	 * @param val The environment variable value.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder environment(String key, String val) {
		pb.environment().put(key, val);
		return this;
	}

	/**
	 * Sets the directory where the command will be executed.
	 *
	 * @param directory The directory.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder directory(File directory) {
		pb.directory(directory);
		return this;
	}

	/**
	 * Sets the maximum allowed return code on the process call.
	 *
	 * <p>
	 * If the return code exceeds this value, an IOException is returned on the {@link #run()} command.
	 * The default value is '0'.
	 *
	 * @param maxExitStatus The maximum exit status.
	 * @return This object (for method chaining).
	 */
	public ProcBuilder maxExitStatus(int maxExitStatus) {
		this.maxExitStatus = maxExitStatus;
		return this;
	}

	/**
	 * Run this command and pipes the output to the specified writer or output stream.
	 *
	 * @return The exit code from the process.
	 * @throws IOException Thrown by underlying stream.
	 * @throws InterruptedException Thread was interrupted.
	 */
	public int run() throws IOException, InterruptedException {
		if (pb.command().size() == 0)
			throw new IOException("No command specified in ProcBuilder.");
		try {
			logWriters.append(divider).append('\n').flush();
			logWriters.append(join(pb.command(), " ")).append('\n').flush();
			p = pb.start();
			IOPipe.create(p.getInputStream(), outWriters).lineProcessor(lp).byLines(byLines).run();
			int rc = p.waitFor();
			logWriters.append("Exit: ").append(String.valueOf(p.exitValue())).append('\n').flush();
			if (rc > maxExitStatus)
				throw new IOException("Return code "+rc+" from command " + join(pb.command(), " "));
			return rc;
		} finally {
			close();
		}
	}

	/**
	 * Run this command and returns the output as a simple string.
	 *
	 * @return The output from the command.
	 * @throws IOException Thrown by underlying stream.
	 * @throws InterruptedException Thread was interrupted.
	 */
	public String getOutput() throws IOException, InterruptedException {
		StringWriter sw = new StringWriter();
		pipeTo(sw).run();
		return sw.toString();
	}

	/**
	 * Returns the output from this process as a {@link Scanner}.
	 *
	 * @return The output from the process as a Scanner object.
	 * @throws IOException Thrown by underlying stream.
	 * @throws InterruptedException Thread was interrupted.
	 */
	public Scanner getScanner() throws IOException, InterruptedException {
		StringWriter sw = new StringWriter();
		pipeTo(sw, true);
		run();
		return new Scanner(sw.toString());
	}

	/**
	 * Destroys the underlying process.
	 *
	 * <p>
	 * This method is only needed if the {@link #getScanner()} method was used.
	 */
	private void close() {
		closeQuietly(logWriters, outWriters);
		if (p != null)
			p.destroy();
	}

	/**
	 * Specifies interface for defining OS-specific commands.
	 */
	public abstract static class Matcher {
		abstract boolean matches();
	}

	static final String OS = System.getProperty("os.name").toLowerCase();

	/** Operating system matcher: Any operating system. */
	public static final Matcher ANY = new Matcher() {
		@Override boolean matches() {
			return true;
		}
	};

	/** Operating system matcher: Any Windows system. */
	public static final Matcher WINDOWS = new Matcher() {
		@Override boolean matches() {
			return OS.indexOf("win") >= 0;
		}
	};

	/** Operating system matcher: Any Mac system. */
	public static final Matcher MAC = new Matcher() {
		@Override boolean matches() {
			return OS.indexOf("mac") >= 0;
		}
	};

	/** Operating system matcher: Any Unix or Linux system. */
	public static final Matcher UNIX = new Matcher() {
		@Override boolean matches() {
			return OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0;
		}
	};

	private static List<String> toList(Object...args) {
		List<String> l = new LinkedList<>();
		for (Object o : args) {
			if (o.getClass().isArray())
				for (int i = 0; i < Array.getLength(o); i++)
					l.add(Array.get(o, i).toString());
			else if (o instanceof Collection)
				for (Object o2 : (Collection<?>)o)
					l.add(o2.toString());
			else
				l.add(o.toString());
		}
		return l;
	}
}
