/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.config.tenant.commands;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;

/**
 * Represents a command identifier. It contains the following parts:
 * <ul>
 * <li>A command name.</li>
 * <li>A list of {@link CommandParameter}.</li>
 * </ul>
 * Each MutuallyExclusiveCommand is capable to generate a {@link org.apache.commons.cli.Option} to be used by the command
 * parser.
 */
public enum MutuallyExclusiveCommand {

	HELP("h") {
		@Override
		public List<CommandParameter> getCommandParameters() {
			return new ArrayList<>(0);
		}

		@Override
		public Option generateOption() {
			return Option.builder("h").longOpt("help").desc("Prints help.").build();
		}
	},
	GENERATE_TENANT("generate") {
		@Override
		public List<CommandParameter> getCommandParameters() {
			final List<CommandParameter> commandParams = new ArrayList<>();
			Collections.addAll(commandParams, CommandParameter.TENANT_NAME, CommandParameter.OUTPUT);
			return commandParams;
		}

		@Override
		public Option generateOption() {
			return Option.builder(getCommandName()).longOpt("generateCSR").desc("generates the CSR and keystore.").build();
		}
	},
	UPDATE_KEYSTORE("update") {
		@Override
		public List<CommandParameter> getCommandParameters() {
			final List<CommandParameter> commandParams = new ArrayList<>();
			Collections.addAll(commandParams, CommandParameter.TENANT_CERTIFICATE,CommandParameter.PLATFORM_ROOT_CA,
				CommandParameter.KEYSTORE_PATH);
			return commandParams;
		}

		@Override
		public Option generateOption() {
			return Option.builder(getCommandName()).longOpt("updatekeystore")
				.desc("updates the generated keystore with a valid certificate chain").build();
		}
	};

	private final String commandName;

	MutuallyExclusiveCommand(final String commandName) {
		this.commandName = commandName;
	}

	/**
	 * Gets command name.
	 *
	 * @return the command name
	 */
	public String getCommandName() {
		return commandName;
	}

	/**
	 * Gets the list of command parameters of this {@link MutuallyExclusiveCommand}.
	 *
	 * @return the list of command parameters of this {@link MutuallyExclusiveCommand}
	 */
	public abstract List<CommandParameter> getCommandParameters();

	/**
	 * Generate {@link org.apache.commons.cli.Option} to be used by the command parser.
	 *
	 * @return the option to be used by the command parser
	 */
	public abstract Option generateOption();

	/**
	 * Gets commands option group composed by all {@link MutuallyExclusiveCommand} options.
	 *
	 * @return the commands option group composed by all {@link MutuallyExclusiveCommand} options.
	 */
	public static OptionGroup getCommandsOptionGroup() {
		final OptionGroup optionGroup = new OptionGroup();
		for (final MutuallyExclusiveCommand mutuallyExclusiveCommand : values()) {
			optionGroup.addOption(mutuallyExclusiveCommand.generateOption());
		}
		return optionGroup;
	}

}
