/**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool 
          with fuzzy matching, translation memory, keyword search, 
          glossaries, and translation leveraging into updated projects.

 Copyright (C) 2015 Aaron Madlon-Kay, Thomas Cordonnier
               2018-2021 Thomas Cordonnier
               Home page: http://www.omegat.org/
               Support center: http://groups.yahoo.com/group/OmegaT/

 This file is part of OmegaT.

 OmegaT is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 OmegaT is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/

package org.omegat;

import java.util.Locale;

import org.omegat.util.OStrings;

/**
 * A class to hold all command-line arguments understood by OmegaT.
 * <p>
 * See also: COMMAND_LINE_HELP in Bundle.properties
 * 
 * @author Aaron Madlon-Kay
 * @author Thomas Cordonnier
 */
public class CLIParameters {

    // Help
    public static final String HELP_SHORT = "-h";
    public static final String HELP = "--help";

    // All modes
    public static final String MODE = "mode";
    public static final String CONFIG_FILE = "config-file";
    public static final String RESOURCE_BUNDLE = "resource-bundle";
    public static final String CONFIG_DIR = "config-dir";
    public static final String DISABLE_PROJECT_LOCKING = "disable-project-locking";
    public static final String DISABLE_LOCATION_SAVE = "disable-location-save";
    /** CLI parameter to disable team functionality (treat as local project) */
    public static final String NO_TEAM = "no-team";
    /** CLI parameter to specify source tokenizer */
    public static final String TOKENIZER_SOURCE = "ITokenizer";
    /** CLI parameter to specify target tokenizer */
    public static final String TOKENIZER_TARGET = "ITokenizerTarget";
    /** CLI parameter to specify source tokenizer behavior mode */
    public static final String TOKENIZER_BEHAVIOR_SOURCE = "ITokenizerBehavior";
    /** CLI parameter to specify target tokenizer behavior mode */
    public static final String TOKENIZER_BEHAVIOR_TARGET = "ITokenizerTargetBehavior";
    // TODO: Document this; see RealProject.patchFileNameForEntryKey()
    public static final String ALTERNATE_FILENAME_FROM = "alternate-filename-from";
    // TODO: Document this; see RealProject.patchFileNameForEntryKey()
    public static final String ALTERNATE_FILENAME_TO = "alternate-filename-to";

    // Non-GUI modes only
    public static final String QUIET = "quiet";
    public static final String SCRIPT = "script";
    public static final String TAG_VALIDATION = "tag-validation";

    // CONSOLE_TRANSLATE mode
    public static final String SOURCE_PATTERN = "source-pattern";

    // CONSOLE_CREATEPSEUDOTRANSLATETMX mode
    public static final String PSEUDOTRANSLATETMX = "pseudotranslatetmx";
    public static final String PSEUDOTRANSLATETYPE = "pseudotranslatetype";

    // CONSOLE_ALIGN mode
    public static final String ALIGNDIR = "alignDir";

    /**
     * Application execution mode. Value of {@link #MODE}.
     */
    enum RUN_MODE {
        GUI, CONSOLE_TRANSLATE, CONSOLE_CREATEPSEUDOTRANSLATETMX, CONSOLE_ALIGN, 
        CONSOLE_INDEX_MEMORY, CONSOLE_INDEX_GLOSSARY, CONSOLE_EXTRACT_XLIFF, CONSOLE_CALC_STATS;
        public static RUN_MODE parse(String s) {
            try {
                return valueOf(normalize(s));
            } catch (Exception ex) {
                // default mode
                return GUI;
            }
        }
        public CharSequence toCommandLineString() {
            return this.toString().replace('_','-').toLowerCase();
        }
    }

    /**
     * Behavior when validating tags. Value of {@link #TAG_VALIDATION}.
     */
    public enum TAG_VALIDATION_MODE {
        IGNORE, WARN, ABORT;
        public static TAG_VALIDATION_MODE parse(String s) {
            try {
                return valueOf(normalize(s));
            } catch (Exception ex) {
                // default mode
                return IGNORE;
            }
        }
    }

    private static String normalize(String s) {
        return s.toUpperCase(Locale.ENGLISH).replace('-', '_');
    }
	
	/** Displayed when you run Omegat --help **/
	public static String help(String type) {
		StringBuilder builder = new StringBuilder();
		builder.append(OStrings.getNameAndVersion()).append("\n\n");
		builder.append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX")).append("\n\n");
		
		if (type == null) {
			builder.append(OStrings.getString("COMMAND_LINE_HELP_SUB_OPTIONS")).append("\n\n");
		} else if (type.toLowerCase().startsWith("options")) {
			builder.append(OStrings.getString("COMMAND_LINE_HELP_OPTIONS")).append("\n");
			builder.append("\t").append(OStrings.getString("COMMAND_LINE_HELP_PATH_ONLY")).append("\n");
			builder.append("\t").append(OStrings.getString("COMMAND_LINE_HELP_NO_OPTION")).append("\n");
			// Named options. Since command line is in english, option names should stay outside translation bundle
			builder.append("\t-h, --help\n").append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_HELP")).append("\n");
			// --mode option is dynamically created: if we add a new mode, it should appear here even if not documented
			builder.append("\t--" + CLIParameters.MODE + "=[").append(String.join("|", java.util.Arrays.stream(RUN_MODE.values()).map(rm -> rm.toCommandLineString())::iterator)).append("]\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_MODE")).append("\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_SUB_MODE")).append("\n");
			builder.append("\t--" + CLIParameters.CONFIG_FILE + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_CONFIG_FILE")).append("\n");
			builder.append("\t--" + CLIParameters.RESOURCE_BUNDLE + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_RESOURCE_BUNDLE")).append("\n");
			builder.append("\t--" + CLIParameters.CONFIG_DIR + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_CONFIG_DIR")).append("\n");
			builder.append("\t--" + CLIParameters.DISABLE_PROJECT_LOCKING +"\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_DISABLE_PROJECT_LOCKING")).append("\n");
			builder.append("\t--" + CLIParameters.DISABLE_LOCATION_SAVE +"\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_DISABLE_LOCATION_SAVE")).append("\n");
			builder.append("\t--" + CLIParameters.NO_TEAM +"\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_NO_TEAM")).append("\n");
			builder.append("\t--" + CLIParameters.TOKENIZER_SOURCE + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_CLASSNAME")).append(">\n");
			builder.append("\t--" + CLIParameters.TOKENIZER_TARGET + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_CLASSNAME")).append(">\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TOKENIZER")).append("\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TOKENIZER_LIST")).append("\n");
			builder.append("\t--" + CLIParameters.TOKENIZER_BEHAVIOR_SOURCE + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_VERSION")).append(">\n");
			builder.append("\t--" + CLIParameters.TOKENIZER_BEHAVIOR_TARGET + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_VERSION")).append(">\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TOKENIZER_BEHAVIOUR")).append("\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TOKENIZER_BEHAVIOUR_DOC")).append("\n");
			builder.append("\t\thttps://lucene.apache.org/core/3_6_0/api/core/org/apache/lucene/util/Version.html\n"); // hardcoded because depends on Lucene version, not on user language
			
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_NON_GUI")).append("\n");
			builder.append("\t--" + CLIParameters.QUIET + "\n").append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_QUIET")).append("\n");
			builder.append("\t--" + CLIParameters.SCRIPT + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_SCRIPT")).append("\n");
			builder.append("\t--" + CLIParameters.TAG_VALIDATION + "=[abort|warn]\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TAG_VALIDATION")).append("\n");
			builder.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_TAG_VALIDATION_WARN")).append("\n");			
		} else if (type.toLowerCase().startsWith("mode:console-translate")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_CONSOLE_TRANSLATE")).append("\n");
			builder.append("\t--" + CLIParameters.SOURCE_PATTERN + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATTERN")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_SOURCE_PATTERN")).append("\n");			
		} else if (type.toLowerCase().startsWith("mode:console-createpseudotranslatetmx")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_PSEUDO_TRANSLATE")).append("\n");
			builder.append("\t--" + CLIParameters.PSEUDOTRANSLATETMX + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_PSEUDO_TRANSLATE_TMX")).append("\n");
			builder.append("\t--" + CLIParameters.PSEUDOTRANSLATETYPE + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_CLASSNAME")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_PSEUDO_TRANSLATE_TYPE")).append("\n");
		} else if (type.toLowerCase().startsWith("mode:console-align")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_CONSOLE_ALIGN")).append("\n");
			builder.append("\t--" + CLIParameters.ALIGNDIR + "=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_ALIGN_DIR")).append("\n");
		} else if (type.toLowerCase().startsWith("mode:console-index-memory")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_CONSOLE_INDEX_MEMORY")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_INDEX_MEMORY_PATHS")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_ROLE_CONSOLE_INDEX_MEMORY_PATHS")).append("\n");
			builder.append("\t--source=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_SOURCE_PATH")).append("\n");
			builder.append("\t--target=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_TARGET_PATH")).append("\n");
			builder.append("\t--source-lang=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_LANG")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_SOURCE_LANG")).append("\n");
			builder.append("\t--target-lang=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_LANG")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_TARGET_LANG")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_INDEX_MEMORY_PROJECT")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_ROLE_CONSOLE_INDEX_MEMORY_PROJECT")).append("\n");
			builder.append("\t--save-files").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_SAVE_FILES")).append("\n");
			builder.append("\t--save-to=<").append(OStrings.getString("COMMAND_LINE_HELP_PARAM_PATH")).append(">\n\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_INDEX_MEMORY_SAVE_TO")).append("\n");
		} else if (type.toLowerCase().startsWith("mode:console-extract-xliff")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_CONSOLE_EXTRACT_XLIFF")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_ROLE_CONSOLE_EXTRACT_XLIFF")).append("\n\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_EXTRACT_XLIFF_PROJ")).append("\n");
			builder.append("\t").append(OStrings.getString("COMMAND_LINE_HELP_ACTION_CONSOLE_EXTRACT_XLIFF_PROJ")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_EXTRACT_XLIFF_FILE")).append("\n");
			builder.append("\t").append(OStrings.getString("COMMAND_LINE_HELP_ACTION_CONSOLE_EXTRACT_XLIFF_FILE")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_EXTRACT_XLIFF_DIR")).append("\n");
			builder.append("\t").append(OStrings.getString("COMMAND_LINE_HELP_ACTION_CONSOLE_EXTRACT_XLIFF_DIR")).append("\n");
		} else if (type.toLowerCase().startsWith("mode:console-calc-stats")) {
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MODE_CONSOLE_EXTRACT_XLIFF")).append("\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_ROLE_CONSOLE_EXTRACT_XLIFF")).append("\n\n");
			builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_SYNTAX_CONSOLE_CALC_STATS")).append("\n");
			builder.append("\t--stats-mode=(STANDARD|MATCHES|MATCHES_PER_FILE)\n")
				.append("\t\t").append(OStrings.getString("COMMAND_LINE_HELP_OPTION_STATS_MODE")).append("\n");
		} else {
			builder.append(OStrings.getString("COMMAND_LINE_HELP_SUB_UNKNOWN")).append(type).append("\n\n");			
		}
		
		builder.append("\n").append(OStrings.getString("COMMAND_LINE_HELP_MANUAL")).append("\n");		
		
		return builder.toString();
	}	
}
