// ***************************************************************************************************************************
// * 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.microservice;

import static org.apache.juneau.internal.FileUtils.*;
import static org.apache.juneau.internal.IOUtils.*;
import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.internal.ObjectUtils.*;

import java.io.*;
import java.net.*;
import java.nio.file.Paths;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.jar.*;
import java.util.logging.*;
import java.util.logging.Formatter;

import org.apache.juneau.*;
import org.apache.juneau.config.*;
import org.apache.juneau.config.event.*;
import org.apache.juneau.config.store.*;
import org.apache.juneau.config.vars.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.microservice.console.*;
import org.apache.juneau.microservice.resources.*;
import org.apache.juneau.parser.ParseException;
import org.apache.juneau.svl.*;
import org.apache.juneau.svl.vars.ManifestFileVar;
import org.apache.juneau.utils.*;

/**
 * Parent class for all microservices.
 *
 * <p>
 * A microservice defines a simple API for starting and stopping simple Java services contained in executable jars.
 *
 * <p>
 * The general command for creating and starting a microservice from a main method is as follows:
 * <p class='bcode w800'>
 * 	<jk>public static void</jk> main(String[] args) {
 * 		Microservice.<jsm>create</jsm>().args(args).build().start().join();
 *  }
 * </p>
 *
 * <p>
 * Your microservice class must be specified as the <jk>Main-Class</jk> entry in the manifest file of your microservice
 * jar file if it's an executable jar.
 *
 * <h5 class='topic'>Microservice Configuration</h5>
 *
 * This class defines the following method for accessing configuration for your microservice:
 * <ul class='spaced-list'>
 * 	<li>
 * 		{@link #getArgs()} - The command-line arguments passed to the jar file.
 * 	<li>
 * 		{@link #getConfig()} - An external INI-style configuration file.
 * 	<li>
 * 		{@link #getManifest()} - The manifest file for the main jar file.
 * </ul>
 *
 * <h5 class='topic'>Lifecycle Methods</h5>
 *
 * Subclasses must implement the following lifecycle methods:
 * <ul class='spaced-list'>
 * 	<li>
 * 		{@link #init()} - Gets executed immediately following construction.
 * 	<li>
 * 		{@link #start()} - Gets executed during startup.
 * 	<li>
 * 		{@link #stop()} - Gets executed when 'exit' is typed in the console or an external shutdown signal is received.
 * 	<li>
 * 		{@link #kill()} - Can be used to forcibly shut down the service.  Doesn't get called during normal operation.
 * </ul>
 */
public class Microservice implements ConfigEventListener {

	private static volatile Microservice INSTANCE;

	private static void setInstance(Microservice m) {
		synchronized(Microservice.class) {
			INSTANCE = m;
		}
	}

	/**
	 * Returns the Microservice instance.
	 *
	 * <p>
	 * This method only works if there's only one Microservice instance in a JVM.
	 * Otherwise, it's just overwritten by the last instantiated microservice.
	 *
	 * @return The Microservice instance, or <jk>null</jk> if there isn't one.
	 */
	public static Microservice getInstance() {
		synchronized(Microservice.class) {
			return INSTANCE;
		}
	}


	final MessageBundle messages = MessageBundle.create(Microservice.class);

	//-----------------------------------------------------------------------------------------------------------------
	// Properties set in constructor
	//-----------------------------------------------------------------------------------------------------------------
	private final MicroserviceBuilder builder;
	private final Args args;
	private final Config config;
	private final ManifestFile manifest;
	private final VarResolver varResolver;
	private final MicroserviceListener listener;
	private final Map<String,ConsoleCommand> consoleCommandMap = new ConcurrentHashMap<>();
	private final boolean consoleEnabled;
	private final Scanner consoleReader;
	private final PrintWriter consoleWriter;
	private final Thread consoleThread;
	final File workingDir;
	private final String configName;

	//-----------------------------------------------------------------------------------------------------------------
	// Properties set in init()
	//-----------------------------------------------------------------------------------------------------------------
	private volatile Logger logger;

	/**
	 * Creates a new microservice builder.
	 *
	 * @return A new microservice builder.
	 */
	public static MicroserviceBuilder create() {
		return new MicroserviceBuilder();
	}

	/**
	 * Constructor.
	 *
	 * @param builder The builder containing the settings for this microservice.
	 * @throws IOException Problem occurred reading file.
	 * @throws ParseException Malformed input encountered.
	 */
	@SuppressWarnings("resource")
	protected Microservice(MicroserviceBuilder builder) throws IOException, ParseException {
		setInstance(this);
		this.builder = builder.copy();
		this.workingDir = builder.workingDir;
		this.configName = builder.configName;

		this.args = builder.args != null ? builder.args : new Args(new String[0]);

		// --------------------------------------------------------------------------------
		// Try to get the manifest file if it wasn't already set.
		// --------------------------------------------------------------------------------
		ManifestFile manifest = builder.manifest;
		if (manifest == null) {
			Manifest m = new Manifest();

			// If running within an eclipse workspace, need to get it from the file system.
			File f = resolveFile("META-INF/MANIFEST.MF");
			if (f.exists() && f.canRead()) {
				try (FileInputStream fis = new FileInputStream(f)) {
					m.read(fis);
				} catch (IOException e) {
					throw new IOException("Problem detected in MANIFEST.MF.  Contents below:\n " + read(f), e);
				}
			} else {
				// Otherwise, read from manifest file in the jar file containing the main class.
				URL url = getClass().getResource("META-INF/MANIFEST.MF");
				if (url != null) {
					try {
						m.read(url.openStream());
					} catch (IOException e) {
						throw new IOException("Problem detected in MANIFEST.MF.  Contents below:\n " + read(url.openStream()), e);
					}
				}
			}
			manifest = new ManifestFile(m);
		}
		ManifestFileVar.init(manifest);
		this.manifest = manifest;

		// --------------------------------------------------------------------------------
		// Try to resolve the configuration if not specified.
		// --------------------------------------------------------------------------------
		Config config = builder.config;
		ConfigBuilder configBuilder = builder.configBuilder.varResolver(builder.varResolverBuilder.build()).store(ConfigMemoryStore.DEFAULT);
		if (config == null) {
			ConfigStore store = builder.configStore;
			ConfigFileStore cfs = workingDir == null ? ConfigFileStore.DEFAULT : ConfigFileStore.create().directory(workingDir).build();
			for (String name : getCandidateConfigNames()) {
				 if (store != null) {
					 if (store.exists(name)) {
						 configBuilder.store(store).name(name);
						 break;
					 }
				 } else {
					 if (cfs.exists(name)) {
						 configBuilder.store(cfs).name(name);
						 break;
					 }
					 if (ConfigClasspathStore.DEFAULT.exists(name)) {
						 configBuilder.store(ConfigClasspathStore.DEFAULT).name(name);
						 break;
					 }
				 }
			}
			config = configBuilder.build();
		}
		this.config = config;
		Config.setSystemDefault(this.config);
		this.config.addListener(this);

		//-------------------------------------------------------------------------------------------------------------
		// Var resolver.
		//-------------------------------------------------------------------------------------------------------------
		VarResolverBuilder varResolverBuilder = builder.varResolverBuilder;
		this.varResolver = varResolverBuilder.contextObject(ConfigVar.SESSION_config, config).build();

		// --------------------------------------------------------------------------------
		// Initialize console commands.
		// --------------------------------------------------------------------------------
		this.consoleEnabled = ObjectUtils.firstNonNull(builder.consoleEnabled, config.getBoolean("Console/enabled", false));
		if (consoleEnabled) {
			Console c = System.console();
			this.consoleReader = ObjectUtils.firstNonNull(builder.consoleReader, new Scanner(c == null ? new InputStreamReader(System.in) : c.reader()));
			this.consoleWriter = ObjectUtils.firstNonNull(builder.consoleWriter, c == null ? new PrintWriter(System.out, true) : c.writer());

			for (ConsoleCommand cc : builder.consoleCommands) {
				consoleCommandMap.put(cc.getName(), cc);
			}
			for (String s : config.getStringArray("Console/commands")) {
				ConsoleCommand cc;
				try {
					cc = (ConsoleCommand)Class.forName(s).newInstance();
					consoleCommandMap.put(cc.getName(), cc);
				} catch (Exception e) {
					getConsoleWriter().println("Could not create console command '"+s+"', " + e.getLocalizedMessage());
				}
			}
			consoleThread = new Thread("ConsoleThread") {
				@Override /* Thread */
				public void run() {
					Scanner in = getConsoleReader();
					PrintWriter out = getConsoleWriter();

					out.println(messages.getString("ListOfAvailableCommands"));
					for (ConsoleCommand cc : new TreeMap<>(getConsoleCommands()).values())
						out.append("\t").append(cc.getName()).append(" -- ").append(cc.getInfo()).println();
					out.println();

					while (true) {
						String line = null;
						out.append("> ").flush();
						line = in.nextLine();
						Args args = new Args(line);
						if (! args.isEmpty())
							executeCommand(args, in, out);
					}
				}
			};
			consoleThread.setDaemon(true);
		} else {
			this.consoleReader = null;
			this.consoleWriter = null;
			this.consoleThread = null;
		}

		//-------------------------------------------------------------------------------------------------------------
		// Other.
		//-------------------------------------------------------------------------------------------------------------
		this.listener = builder.listener != null ? builder.listener : new BasicMicroserviceListener();

		init();
	}

	private List<String> getCandidateConfigNames() {
		if (configName != null)
			return Collections.singletonList(configName);

		Args args = getArgs();
		if (getArgs().hasArg("configFile"))
			return Collections.singletonList(args.getArg("configFile"));

		ManifestFile manifest = getManifest();
		if (manifest.containsKey("Main-Config"))
			return Collections.singletonList(manifest.getString("Main-Config"));

		return Config.getCandidateSystemDefaultConfigNames();
	}

	/**
	 * Resolves the specified path.
	 *
	 * <p>
	 * If the working directory has been explicitly specified, relative paths are resolved relative to that.
	 *
	 * @param path The path to resolve.
	 * @return The resolved path.
	 */
	protected File resolveFile(String path) {
		if (Paths.get(path).isAbsolute())
			return new File(path);
		if (workingDir != null)
			return new File(workingDir, path);
		return new File(path);
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Abstract lifecycle methods.
	//-----------------------------------------------------------------------------------------------------------------

	/**
	 * Initializes this microservice.
	 *
	 * <p>
	 * This method can be called whenever the microservice is not started.
	 *
	 * <p>
	 * It will initialize (or reinitialize) the console commands, system properties, and logger.
	 *
	 * @return This object (for method chaining).
	 * @throws ParseException Malformed input encountered.
	 * @throws IOException Couldn't read a file.
	 */
	public synchronized Microservice init() throws IOException, ParseException {

		// --------------------------------------------------------------------------------
		// Set system properties.
		// --------------------------------------------------------------------------------
		Set<String> spKeys = config.getKeys("SystemProperties");
		if (spKeys != null)
			for (String key : spKeys)
				System.setProperty(key, config.getString("SystemProperties/"+key));

		// --------------------------------------------------------------------------------
		// Initialize logging.
		// --------------------------------------------------------------------------------
		this.logger = builder.logger;
		LogConfig logConfig = builder.logConfig != null ? builder.logConfig : new LogConfig();
		if (this.logger == null) {
			LogManager.getLogManager().reset();
			this.logger = Logger.getLogger("");
			String logFile = firstNonNull(logConfig.logFile, config.getString("Logging/logFile"));

			if (isNotEmpty(logFile)) {
				String logDir = firstNonNull(logConfig.logDir, config.getString("Logging/logDir", "."));
				File logDirFile = resolveFile(logDir);
				mkdirs(logDirFile, false);
				logDir = logDirFile.getAbsolutePath();
				System.setProperty("juneau.logDir", logDir);

				boolean append = firstNonNull(logConfig.append, config.getBoolean("Logging/append"));
				int limit = firstNonNull(logConfig.limit, config.getInt("Logging/limit", 1024*1024));
				int count = firstNonNull(logConfig.count, config.getInt("Logging/count", 1));

				FileHandler fh = new FileHandler(logDir + '/' + logFile, limit, count, append);

				Formatter f = logConfig.formatter;
				if (f == null) {
					String format = config.getString("Logging/format", "[{date} {level}] {msg}%n");
					String dateFormat = config.getString("Logging/dateFormat", "yyyy.MM.dd hh:mm:ss");
					boolean useStackTraceHashes = config.getBoolean("Logging/useStackTraceHashes");
					f = new LogEntryFormatter(format, dateFormat, useStackTraceHashes);
				}
				fh.setFormatter(f);
				fh.setLevel(firstNonNull(logConfig.fileLevel, config.getObjectWithDefault("Logging/fileLevel", Level.INFO, Level.class)));
				logger.addHandler(fh);

				ConsoleHandler ch = new ConsoleHandler();
				ch.setLevel(firstNonNull(logConfig.consoleLevel, config.getObjectWithDefault("Logging/consoleLevel", Level.WARNING, Level.class)));
				ch.setFormatter(f);
				logger.addHandler(ch);
			}
		}

		ObjectMap loggerLevels = config.getObject("Logging/levels", ObjectMap.class);
		if (loggerLevels != null)
			for (String l : loggerLevels.keySet())
				Logger.getLogger(l).setLevel(loggerLevels.get(l, Level.class));
		for (String l : logConfig.levels.keySet())
			Logger.getLogger(l).setLevel(logConfig.levels.get(l));

		return this;
	}

	/**
	 * Start this application.
	 *
	 * <p>
	 * Overridden methods MUST call this method FIRST so that the {@link MicroserviceListener#onStart(Microservice)} method is called.
	 *
	 * @return This object (for method chaining).
	 * @throws Exception Error occurred.
	 */
	public synchronized Microservice start() throws Exception {

		if (config.getName() == null)
			err(messages, "RunningClassWithoutConfig", getClass().getSimpleName());
		else
			out(messages, "RunningClassWithConfig", getClass().getSimpleName(), config.getName());

		Runtime.getRuntime().addShutdownHook(
			new Thread("ShutdownHookThread") {
				@Override /* Thread */
				public void run() {
					try {
						Microservice.this.stop();
						Microservice.this.stopConsole();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		);

		listener.onStart(this);

		return this;
	}

	/**
	 * Starts the console thread for this microservice.
	 *
	 * @return This object (for method chaining).
	 * @throws Exception Error occurred
	 */
	public synchronized Microservice startConsole() throws Exception {
		if (consoleThread != null && ! consoleThread.isAlive())
			consoleThread.start();
		return this;
	}

	/**
	 * Stops the console thread for this microservice.
	 *
	 * @return This object (for method chaining).
	 * @throws Exception Error occurred
	 */
	public synchronized Microservice stopConsole() throws Exception {
		if (consoleThread != null && consoleThread.isAlive())
			consoleThread.interrupt();
		return this;
	}

	/**
	 * Returns the command-line arguments passed into the application.
	 *
	 * <p>
	 * This method can be called from the class constructor.
	 *
	 * <p>
	 * See {@link Args} for details on using this method.
	 *
	 * @return The command-line arguments passed into the application.
	 */
	public Args getArgs() {
		return args;
	}

	/**
	 * Returns the external INI-style configuration file that can be used to configure your microservice.
	 *
	 * <p>
	 * The config location is determined in the following order:
	 * <ol class='spaced-list'>
	 * 	<li>
	 * 		The first argument passed to the microservice jar.
	 * 	<li>
	 * 		The <c>Main-Config</c> entry in the microservice jar manifest file.
	 * 	<li>
	 * 		The name of the microservice jar with a <js>".cfg"</js> suffix (e.g.
	 * 		<js>"mymicroservice.jar"</js>-&gt;<js>"mymicroservice.cfg"</js>).
	 * </ol>
	 *
	 * <p>
	 * If all methods for locating the config fail, then this method returns an empty config.
	 *
	 * <p>
	 * Subclasses can set their own config file by using the following methods:
	 * <ul class='javatree'>
	 * 	<li class='jm'>{@link MicroserviceBuilder#configStore(ConfigStore)}
	 * 	<li class='jm'>{@link MicroserviceBuilder#configName(String)}
	 * </ul>
	 *
	 * <p>
	 * String variables are automatically resolved using the variable resolver returned by {@link #getVarResolver()}.
	 *
	 * <p>
	 * This method can be called from the class constructor.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<cc>#--------------------------</cc>
	 * 	<cc># My section</cc>
	 * 	<cc>#--------------------------</cc>
	 * 	<cs>[MySection]</cs>
	 *
	 * 	<cc># An integer</cc>
	 * 	<ck>anInt</ck> = 1
	 *
	 * 	<cc># A boolean</cc>
	 * 	<ck>aBoolean</ck> = true
	 *
	 * 	<cc># An int array</cc>
	 * 	<ck>anIntArray</ck> = 1,2,3
	 *
	 * 	<cc># A POJO that can be converted from a String</cc>
	 * 	<ck>aURL</ck> = http://foo
	 *
	 * 	<cc># A POJO that can be converted from JSON</cc>
	 * 	<ck>aBean</ck> = {foo:'bar',baz:123}
	 *
	 * 	<cc># A system property</cc>
	 * 	<ck>locale</ck> = $S{java.locale, en_US}
	 *
	 * 	<cc># An environment variable</cc>
	 * 	<ck>path</ck> = $E{PATH, unknown}
	 *
	 * 	<cc># A manifest file entry</cc>
	 * 	<ck>mainClass</ck> = $MF{Main-Class}
	 *
	 * 	<cc># Another value in this config file</cc>
	 * 	<ck>sameAsAnInt</ck> = $C{MySection/anInt}
	 *
	 * 	<cc># A command-line argument in the form "myarg=foo"</cc>
	 * 	<ck>myArg</ck> = $A{myarg}
	 *
	 * 	<cc># The first command-line argument</cc>
	 * 	<ck>firstArg</ck> = $A{0}
	 *
	 * 	<cc># Look for system property, or env var if that doesn't exist, or command-line arg if that doesn't exist.</cc>
	 * 	<ck>nested</ck> = $S{mySystemProperty,$E{MY_ENV_VAR,$A{0}}}
	 *
	 * 	<cc># A POJO with embedded variables</cc>
	 * 	<ck>aBean2</ck> = {foo:'$A{0}',baz:$C{MySection/anInt}}
	 * </p>
	 *
	 * <p class='bcode w800'>
	 * 	<jc>// Java code for accessing config entries above.</jc>
	 * 	Config cf = getConfig();
	 *
	 * 	<jk>int</jk> anInt = cf.getInt(<js>"MySection/anInt"</js>);
	 * 	<jk>boolean</jk> aBoolean = cf.getBoolean(<js>"MySection/aBoolean"</js>);
	 * 	<jk>int</jk>[] anIntArray = cf.getObject(<jk>int</jk>[].<jk>class</jk>, <js>"MySection/anIntArray"</js>);
	 * 	URL aURL = cf.getObject(URL.<jk>class</jk>, <js>"MySection/aURL"</js>);
	 * 	MyBean aBean = cf.getObject(MyBean.<jk>class</jk>, <js>"MySection/aBean"</js>);
	 * 	Locale locale = cf.getObject(Locale.<jk>class</jk>, <js>"MySection/locale"</js>);
	 * 	String path = cf.getString(<js>"MySection/path"</js>);
	 * 	String mainClass = cf.getString(<js>"MySection/mainClass"</js>);
	 * 	<jk>int</jk> sameAsAnInt = cf.getInt(<js>"MySection/sameAsAnInt"</js>);
	 * 	String myArg = cf.getString(<js>"MySection/myArg"</js>);
	 * 	String firstArg = cf.getString(<js>"MySection/firstArg"</js>);
	 * </p>
	 *
	 * @return The config file for this application, or <jk>null</jk> if no config file is configured.
	 */
	public Config getConfig() {
		return config;
	}

	/**
	 * Returns the main jar manifest file contents as a simple {@link ObjectMap}.
	 *
	 * <p>
	 * This map consists of the contents of {@link Manifest#getMainAttributes()} with the keys and entries converted to
	 * simple strings.
	 * <p>
	 * This method can be called from the class constructor.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Get Main-Class from manifest file.</jc>
	 * 	String mainClass = Microservice.<jsm>getManifest</jsm>().getString(<js>"Main-Class"</js>, <js>"unknown"</js>);
	 *
	 * 	<jc>// Get Rest-Resources from manifest file.</jc>
	 * 	String[] restResources = Microservice.<jsm>getManifest</jsm>().getStringArray(<js>"Rest-Resources"</js>);
	 * </p>
	 *
	 * @return The manifest file from the main jar, or <jk>null</jk> if the manifest file could not be retrieved.
	 */
	public ManifestFile getManifest() {
		return manifest;
	}

	/**
	 * Returns the variable resolver for resolving variables in strings and files.
	 *
	 * <p>
	 * Variables can be controlled by the following methods:
	 * <ul class='javatree'>
	 * 	<li class='jm'>{@link MicroserviceBuilder#vars(Class...)}
	 * 	<li class='jm'>{@link MicroserviceBuilder#varContext(String, Object)}
	 * </ul>
	 *
	 * @return The VarResolver used by this Microservice, or <jk>null</jk> if it was never created.
	 */
	public VarResolver getVarResolver() {
		return varResolver;
	}

	/**
	 * Returns the logger for this microservice.
	 *
	 * @return The logger for this microservice.
	 */
	public Logger getLogger() {
		return logger;
	}

	/**
	 * Executes a console command.
	 *
	 * @param args
	 * 	The command arguments.
	 * 	<br>The first entry in the arguments is always the command name.
	 * @param in Console input.
	 * @param out Console output.
	 * @return <jk>true</jk> if the command returned <jk>true</jk> meaning the console thread should exit.
	 */
	public boolean executeCommand(Args args, Scanner in, PrintWriter out) {
		ConsoleCommand cc = consoleCommandMap.get(args.getArg(0));
		if (cc == null) {
			out.println(messages.getString("UnknownCommand"));
		} else {
			try {
				return cc.execute(in, out, args);
			} catch (Exception e) {
				e.printStackTrace(out);
			}
		}
		return false;
	}

	/**
	 * Convenience method for executing a console command directly.
	 *
	 * <p>
	 * Allows you to execute a console command outside the console by simulating input and output.
	 *
	 * @param command The command name to execute.
	 * @param input Optional input to the command.  Can be <jk>null</jk>.
	 * @param args Optional command arguments to pass to the command.
	 * @return The command output.
	 */
	public String executeCommand(String command, String input, Object...args) {
		StringWriter sw = new StringWriter();
		List<String> l = new ArrayList<>();
		l.add(command);
		for (Object a : args)
			l.add(stringify(a));
		Args args2 = new Args(l.toArray(new String[l.size()]));
		try (Scanner in = new Scanner(input); PrintWriter out = new PrintWriter(sw)) {
			executeCommand(args2, in, out);
		}
		return sw.toString();
	}

	/**
	 * Joins the application with the current thread.
	 *
	 * <p>
	 * Default implementation is a no-op.
	 *
	 * @return This object (for method chaining).
	 * @throws Exception Error occurred
	 */
	public Microservice join() throws Exception {
		return this;
	}

	/**
	 * Stop this application.
	 *
	 * <p>
	 * Overridden methods MUST call this method LAST so that the {@link MicroserviceListener#onStop(Microservice)} method is called.
	 *
	 * @return This object (for method chaining).
	 * @throws Exception Error occurred
	 */
	public Microservice stop() throws Exception {
		listener.onStop(this);
		return this;
	}

	/**
	 * Stops the console (if it's started) and calls {@link System#exit(int)}.
	 *
	 * @throws Exception Error occurred
	 */
	public void exit() throws Exception {
		try {
			stopConsole();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.exit(0);
	}

	/**
	 * Kill the JVM by calling <c>System.exit(2);</c>.
	 */
	public void kill() {
		// This triggers the shutdown hook.
		System.exit(2);
	}


	//-----------------------------------------------------------------------------------------------------------------
	// Other methods.
	//-----------------------------------------------------------------------------------------------------------------

	/**
	 * Returns the console commands associated with this microservice.
	 *
	 * @return The console commands associated with this microservice as an unmodifiable map.
	 */
	public final Map<String,ConsoleCommand> getConsoleCommands() {
		return consoleCommandMap;
	}

	/**
	 * Returns the console reader.
	 *
	 * <p>
	 * Subclasses can override this method to provide their own console input.
	 *
	 * @return The console reader.  Never <jk>null</jk>.
	 */
	protected Scanner getConsoleReader() {
		return consoleReader;
	}

	/**
	 * Returns the console writer.
	 *
	 * <p>
	 * Subclasses can override this method to provide their own console output.
	 *
	 * @return The console writer.  Never <jk>null</jk>.
	 */
	protected PrintWriter getConsoleWriter() {
		return consoleWriter;
	}

	/**
	 * Prints a localized message to the console writer.
	 *
	 * <p>
	 * Ignored if <js>"Console/enabled"</js> is <jk>false</jk>.
	 *
	 * @param mb The message bundle containing the message.
	 * @param messageKey The message key.
	 * @param args Optional {@link MessageFormat}-style arguments.
	 */
	public void out(MessageBundle mb, String messageKey, Object...args) {
		String msg = mb.getString(messageKey, args);
		if (consoleEnabled)
			getConsoleWriter().println(msg);
		log(Level.INFO, msg);
	}

	/**
	 * Prints a localized message to STDERR.
	 *
	 * <p>
	 * Ignored if <js>"Console/enabled"</js> is <jk>false</jk>.
	 *
	 * @param mb The message bundle containing the message.
	 * @param messageKey The message key.
	 * @param args Optional {@link MessageFormat}-style arguments.
	 */
	public void err(MessageBundle mb, String messageKey, Object...args) {
		String msg = mb.getString(messageKey, args);
		if (consoleEnabled)
			System.err.println(mb.getString(messageKey, args));  // NOT DEBUG
		log(Level.SEVERE, msg);
	}

	/**
	 * Logs a message to the log file.
	 *
	 * @param level The log level.
	 * @param message The message text.
	 * @param args Optional {@link MessageFormat}-style arguments.
	 */
	protected void log(Level level, String message, Object...args) {
		String msg = args.length == 0 ? message : MessageFormat.format(message, args);
		getLogger().log(level, msg);
	}

	@Override /* ConfigChangeListener */
	public void onConfigChange(ConfigEvents events) {
		listener.onConfigChange(this, events);
	}
}
