content: /**
   * Copyright 2020 Alexander Herzog
   *
   * Licensed 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 systemtools.commandline;
  
  import java.io.InputStream;
  import java.io.PrintStream;
  
  /**
   * Abstrakte Basisklasse aller Kommandozeilenbefehle
   * @author Alexander Herzog
   * @see BaseCommandLineSystem
   */
  public abstract class AbstractCommand {
  	/**
  	 * Referenz auf das Kommandozeilensystem selbst.<br>
  	 * Wird von {@link BaseCommandLineSystem} gesetzt, wenn der Befehl dort registriert wird.<br>
  	 * Kann <code>null</code> sein, wenn der Befehl ber den Dialog ausgefhrt wird.
  	 */
  	protected final BaseCommandLineSystem system;
  
  	/**
  	 * System, um die Ausgabe ber ANSI-Escape-Codes zu formatieren
  	 * @see ANSIFormat
  	 */
  	protected final ANSIFormat style;
  
  	/**
  	 * Konstruktor der Klasse
  	 * @param system	Referenz auf das Kommandozeilensystem
  	 */
  	public AbstractCommand(final BaseCommandLineSystem system) {
  		this.system=system;
  		style=system.getStyle();
  	}
  
  	/**
  	 * Gibt die Namen der Parameter an, die diesen Befehl ausfhren sollen.
  	 * @return	Array aus den Namen der Befehle; die Gro- und Kleinschreibung wird beim spteren Vergleich nicht bercksichtigt
  	 */
  	public abstract String[] getKeys();
  
  	/**
  	 * Gibt den primren Namen des Befehls an, der in der Hilfe angezeigt werden soll.
  	 * Dieser Name sollte mit dem ersten Array-Eintrag von <code>getKeys</code> bereinstimmen.
  	 * @return	Name des Befehls
  	 */
  	public String getName() {
  		return getKeys()[0];
  	}
  
  	/**
  	 * Gibt an, ob der Befehl in der Befehlshilfe aufgelistet werden soll.
  	 * @return	Im Falle von <code>true</code> wird der Befehl in der Hilfe nicht angezeigt.
  	 */
  	public boolean isHidden() {
  		return false;
  	}
  
  	/**
  	 * Kann dieser Befehl ber die GUI verarbeitet werden.
  	 * @return	Im Falle von <code>false</code> wird der Befehl nicht in dem GUI-Kommandozeilen-Dialog angezeigt.
  	 */
  	public boolean isGUIProcessable() {
  		return !isHidden();
  	}
  
  	/**
  	 * Liefert eine kurze, einzeilige Beschreibung des Befehls zurck
  	 * @return	Kurzbeschreibung des Befehls
  	 */
  	public abstract String getShortDescription();
  
  	/**
  	 * Liefert eine lange, mehrzeilige Beschreibung des Befehls inkl.
  	 * Erklrung der weiteren Parameter zurck
  	 * @return	Langbeschreibung des Befehls
  	 */
  	public abstract String[] getLongDescription();
  
  	/**
  	 * Bereitet die Ausfhrung des Befehls vor
  	 * @param additionalArguments	Weitere Kommandozeilenargumente nach dem Befehlsschlsselwort
  	 * @param in	Ein {@link InputStream}-Objekt oder <code>null</code>, ber das Zeichen von der Konsole gelesen werden knnen (<code>null</code>, wenn keine Konsole verfgbar ist)
  	 * @param out	Ein {@link PrintStream}-Objekt, ber das Texte ausgegeben werden knnen.
  	 * @return	Gibt <code>null</code> zurck, wenn die Vorbereitung erfolgreich war, sonst eine Fehlermeldung.
  	 */
  	public String prepare(String[] additionalArguments, InputStream in, PrintStream out) {
  		return null;
  	}
  
  	/**
  	 * Fhrt den Befehl aus.
  	 * @param allCommands	Liste alle registrierten Befehle
  	 * @param in	Ein {@link InputStream}-Objekt oder <code>null</code>, ber das Zeichen von der Konsole gelesen werden knnen (<code>null</code>, wenn keine Konsole verfgbar ist)
  	 * @param out	Ein {@link PrintStream}-Objekt, ber das Texte ausgegeben werden knnen.
  	 */
  	public abstract void run(AbstractCommand[] allCommands, InputStream in, PrintStream out);
  
  	/**
  	 * Prft, ob die angegebene Parameteranzahl korrekt ist und generiert ggf. eine passende Fehlermeldung.
  	 * @param min	Minimale Anzahl an weiteren Parametern (nach dem Befehls-Parameter)
  	 * @param max	Maximale Anzahl an weiteren Parametern (nach dem Befehls-Parameter)
  	 * @param additionalArguments	bergebene weitere Parameter
  	 * @return	Gibt im Erfolgsfall <code>null</code> zurck, sonst eine Fehlermeldung als String.
  	 */
  	protected final String parameterCountCheck(int min, int max, String[] additionalArguments) {
  		String s=String.format(BaseCommandLineSystem.commandCountIf,getName())+" ";
  		String t=". "+String.format(BaseCommandLineSystem.commandCountThenButN,additionalArguments.length);
  		if (additionalArguments.length==0) t=". "+BaseCommandLineSystem.commandCountThenBut0;
  		if (additionalArguments.length==1) t=". "+BaseCommandLineSystem.commandCountThenBut1;
  
  		if (min==max) {
  			if (additionalArguments.length!=min) {
  				if (min==0) return s+BaseCommandLineSystem.commandCountThen0+t;
  				if (min==1) return s+BaseCommandLineSystem.commandCountThen1+t;
  				return s+String.format(BaseCommandLineSystem.commandCountThenN,min);
  			}
  			return null;
  		}
  
  		if (additionalArguments.length<min) {
  			if (min==1) return s+BaseCommandLineSystem.commandCountThenAtLeast1+t;
  			return s+String.format(BaseCommandLineSystem.commandCountThenAtLeastN,min)+t;
  		}
  
  		if (additionalArguments.length>max) {
  			if (max==1) return s+BaseCommandLineSystem.commandCountThenMaximum1+t;
  			return s+String.format(BaseCommandLineSystem.commandCountThenMaximumN,max)+t;
  		}
  
  		return null;
  	}
  
  	/**
  	 * Prft, ob die angegebene Parameteranzahl korrekt ist und generiert ggf. eine passende Fehlermeldung.
  	 * @param count	Geforderte Anzahl an weiteren Parametern (nach dem Befehls-Parameter)
  	 * @param additionalArguments	bergebene weitere Parameter
  	 * @return	Gibt im Erfolgsfall <code>null</code> zurck, sonst eine Fehlermeldung als String.
  	 */
  	protected final String parameterCountCheck(int count, String[] additionalArguments) {
  		return parameterCountCheck(count,count,additionalArguments);
  	}
  
  	/**
  	 * Setzt den Quit-Status (der ggf. an einen Server weitergegeben werden kann).
  	 * (Beim Aufruf ber Kommandozeile nicht ntig, aber z.B. sinnvoll, wenn Betrieb ber GUI.)
  	 */
  	public void setQuit() {}
  }