/*=============================================================================#
 # Copyright (c) 2017, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.server.srv;

import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public class CliUtil {
	
	
	public static final int EXIT_ARGS_MISSING= ServerControl.EXIT_ARGS | 1;
	public static final int EXIT_ARGS_INVALID= ServerControl.EXIT_ARGS | 2;
	
	
	private final String command;
	
	private final String name;
	
	private final Map<String, @Nullable String> options;
	
	
	public CliUtil(final String[] args) {
		int idx= 0;
		if (args.length <= idx || args[idx].startsWith("-")) {
			invalidArgs("Missing server command");
		}
		this.command= args[idx++]; 
		if (!isValidCommand(this.command)) {
			invalidArgs("Invalid server command '" + this.command + "'");
		}
		
		if (isNameCommand(this.command) && args.length <= idx) {
			invalidArgs("Missing server name");
		}
		this.name= args[idx++];
		
		this.options= new HashMap<>();
		while (idx < args.length) {
			final String arg= args[idx++];
			if (arg.isEmpty() || arg.charAt(0) != '-') {
				continue;
			}
			final int split= arg.indexOf('=');
			if (split > 1) {
				this.options.put(arg.substring(1, split), arg.substring(split + 1));
			}
			else if (split < 0) {
				this.options.put(arg.substring(1), null);
			}
		}
		
		checkGlobalOptions();
	}
	
	
	protected boolean isValidCommand(final String command) {
		return (command.equals("start") || command.equals("clean"));
	}
	
	protected boolean isNameCommand(final String command) {
		return true;
	}
	
	protected void checkGlobalOptions() {
		if (Boolean.parseBoolean(System.getProperty("org.eclipse.statet.rj.verbose"))
				|| Boolean.parseBoolean(System.getProperty("org.eclipse.statet.rj.debug")) ) {
			this.options.put("verbose", "true");
		}
		if (this.options.containsKey("log")) {
			try {
				final String fileName= this.options.get("log");
				final Path file= Path.of((fileName != null) ? fileName : "out.log");
				final PrintStream stream= new PrintStream(Files.newOutputStream(file), false,
						StandardCharsets.UTF_8 );
				stream.println("RJ R engine log");
				stream.flush();
				System.setOut(stream);
				System.setErr(stream);
			}
			catch (final Throwable e) {
				e.printStackTrace();
				ServerControl.exit(ServerControl.EXIT_INIT_LOGGING_ERROR);
			}
		}
	}
	
	
	public String getCommand() {
		return this.command;
	}
	
	public String getName() {
		return this.name;
	}
	
	public Map<String, @Nullable String> getOptions() {
		return this.options;
	}
	
	
	public void invalidArgs(final String message) {
		System.err.println(message);
		printHelp();
		ServerControl.exit(EXIT_ARGS_INVALID);
	}
	
	public void printHelp() {
		System.out.println("= Usage of RJserver command line control ================");
		System.out.println("commands:");
		System.out.println("  start <name>    adds server to RMIregistry");
		System.out.println("  clean <name>    stops server/remove from RMIregistry");
		System.out.println("name:             unique name in RMIregistry");
		System.out.println("options:");
		System.out.println("  -verbose        verbose logging");
		System.out.println("  -server         class name of server implementation");
		System.out.println("  -plugins=<..>   list of plugins");
		System.out.println("  -auth=<..>      authetification method");
	}
	
	
}
