/*
 * libbrlapi - A library providing access to braille terminals for applications.
 *
 * Copyright (C) 2006-2023 by
 *   Samuel Thibault <Samuel.Thibault@ens-lyon.org>
 *   Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>
 *
 * libbrlapi comes with ABSOLUTELY NO WARRANTY.
 *
 * This is free software, placed under the terms of the
 * GNU Lesser General Public License, as published by the Free Software
 * Foundation; either version 2.1 of the License, or (at your option) any
 * later version. Please see the file LICENSE-LGPL for details.
 *
 * Web Page: http://brltty.app/
 *
 * This software is maintained by Dave Mielke <dave@mielke.cc>.
 */

package org.a11y.brlapi;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;

public abstract class Program extends ProgramComponent implements Runnable {
  protected abstract void runProgram () throws ProgramException;

  private String programName = null;

  public final boolean isClient () {
    return isClient(this);
  }

  public final String getProgramName() {
    if (programName == null) return getObjectName();
    return programName;
  }

  public final Program setProgramName(String name) {
    programName = name;
    return this;
  }

  protected final void writeProgramMessage (String format, Object... arguments) {
    System.err.println((getObjectName() + ": " + String.format(format, arguments)));
  }

  protected static class Option {
    public final static char PREFIX_CHARACTER = '-';

    public interface Handler {
      public void handleOption (String[] operands) throws SyntaxException;
    }

    private final String optionName;
    private final Handler optionHandler;
    private final String[] operandDescriptions;

    public Option (String name, Handler handler, String... operands) {
      optionName = name;
      optionHandler = handler;
      operandDescriptions = operands;
    }

    public final String getName () {
      return optionName;
    }

    public final Handler getHandler () {
      return optionHandler;
    }

    public final String[] getOperands () {
      int count = operandDescriptions.length;
      String[] result = new String[count];
      System.arraycopy(operandDescriptions, 0, result, 0, count);
      return result;
    }
  }

  private final String[] programArguments;
  private final KeywordMap<Option> programOptions = new KeywordMap<>();

  protected final void addOption (String name, Option.Handler handler, String... operands) {
    programOptions.put(name, new Option(name, handler, operands));
  }

  private List<String> requiredParameters = null;
  private List<String> optionalParameters = null;
  private boolean haveRepeatingParameter = false;

  protected final void addRequiredParameters (String... parameters) {
    if (optionalParameters != null) {
      throw new IllegalStateException("optional parameters already added");
    }

    if (requiredParameters == null) {
      requiredParameters = new ArrayList<>();
    }

    for (String parameter : parameters) {
      requiredParameters.add(parameter);
    }
  }

  protected final void addOptionalParameters (String... parameters) {
    if (haveRepeatingParameter) {
      throw new IllegalStateException("repeating parameter already added");
    }

    if (optionalParameters == null) {
      optionalParameters = new ArrayList<>();
    }

    for (String parameter : parameters) {
      optionalParameters.add(parameter);
    }
  }

  protected final void addRepeatingParameter (String parameter) {
    addOptionalParameters(parameter);
    haveRepeatingParameter = true;
  }

  public String getPurpose() {
    return null;
  }

  protected void extendUsageSummary(StringBuilder usage) {}

  public final static char USAGE_OPTIONAL_BEGIN = '[';
  public final static char USAGE_OPTIONAL_END = ']';
  public final static String USAGE_REPEATING_INDICATOR = "...";

  public final String getUsageSummary () {
    StringBuilder usage = new StringBuilder();
    boolean haveOptions = !programOptions.isEmpty();

    {
      String pattern = "^(.*)(\\p{Upper}.*)$";
      String name = getObjectName();
      Matcher matcher = Strings.getMatcher(pattern, name);
      String phrase;

      if (matcher.matches()) {
        name = matcher.group(1);
        phrase = "the " + name + ' ' + matcher.group(2);
      } else {
        phrase = name;
      }

      usage.append("Usage Summary for ").append(phrase);
    }

    {
      usage.append("\nSyntax: ").append(getProgramName());
      int start = usage.length();

      if (haveOptions) {
        usage.append(' ').append(USAGE_OPTIONAL_BEGIN)
             .append(Option.PREFIX_CHARACTER).append("option")
             .append(' ').append(USAGE_REPEATING_INDICATOR)
             .append(USAGE_OPTIONAL_END);
      }

      if (requiredParameters != null) {
        for (String parameter : requiredParameters) {
          usage.append(' ').append(toOperandName(parameter));
        }
      }

      if (optionalParameters != null) {
        for (String parameter : optionalParameters) {
          usage.append(' ').append(USAGE_OPTIONAL_BEGIN)
               .append(toOperandName(parameter));
        }

        if (haveRepeatingParameter) {
          usage.append(' ').append(USAGE_REPEATING_INDICATOR);
        }

        for (int i=optionalParameters.size(); i>0; i-=1) {
          usage.append(USAGE_OPTIONAL_END);
        }
      }

      if (usage.length() == start) usage.append(" (no arguments)");
    }

    {
      String purpose = getPurpose();

      if ((purpose != null) && !purpose.isEmpty()) {
        usage.append("\n\n").append(purpose);
      }
    }

    if (haveOptions) {
      usage.append("\n\nThese options may be specified:");

      for (String name : programOptions.getKeywords()) {
        Option option = programOptions.get(name);
        usage.append("\n  ").append(Option.PREFIX_CHARACTER).append(name);

        for (String operand : option.getOperands()) {
          usage.append(' ').append(toOperandName(operand));
        }
      }
    }

    {
      StringBuilder extension = new StringBuilder();
      extendUsageSummary(extension);

      String text = Strings.formatParagraphs(extension.toString());
      if (!text.isEmpty()) usage.append("\n\n").append(text);
    }

    return usage.toString();
  }

  protected Program (String... arguments) {
    super();
    programArguments = arguments;

    addOption("help",
      (operands) -> {
        printf("%s\n", getUsageSummary());
        throw new ExitException(EXIT_CODE_SUCCESS);
      }
    );
  }

  protected void processParameters (String[] parameters)
            throws SyntaxException
  {
    if (parameters.length > 0) {
      throw new TooManyParametersException(parameters);
    }
  }

  private final void processArguments (String[] arguments)
          throws SyntaxException
  {
    int argumentCount = arguments.length;
    int argumentIndex = 0;

    while (argumentIndex < argumentCount) {
      String argument = arguments[argumentIndex];
      if (argument.isEmpty()) break;
      if (argument.charAt(0) != Option.PREFIX_CHARACTER) break;

      if (argument.length() == 1) {
        argumentIndex += 1;
        break;
      }

      String name = argument.substring(1).toLowerCase();
      Option option = programOptions.get(name);

      if (option == null) {
        throw new SyntaxException("unknown option: %s", argument);
      }

      String[] operandDescriptions = option.getOperands();
      int operandCount = operandDescriptions.length;

      {
        int index = argumentCount - argumentIndex - 1;

        if (index < operandCount) {
          throw new SyntaxException(
            "missing %s: %c%s",
            operandDescriptions[index],
            Option.PREFIX_CHARACTER,
            option.getName()
          );
        }
      }

      String[] operands = new String[operandCount];
      System.arraycopy(arguments, argumentIndex+1, operands, 0, operandCount);
      option.getHandler().handleOption(operands);

      argumentIndex += 1 + operandCount;
    }

    int parameterCount = argumentCount - argumentIndex;
    String[] parameters = new String[parameterCount];
    System.arraycopy(arguments, argumentIndex, parameters, 0, parameterCount);
    processParameters(parameters);
  }

  protected void onProgramException (ProgramException exception) {
    writeProgramMessage("%s", exception.getMessage());
    int exitCode;

    if (exception instanceof SyntaxException) {
      exitCode = EXIT_CODE_SYNTAX;
    } else if (exception instanceof SemanticException) {
      exitCode = EXIT_CODE_SEMANTIC;
    } else if (exception instanceof ExternalException) {
      exitCode = EXIT_CODE_EXTERNAL;
    } else {
      exitCode = EXIT_CODE_INTERNAL;
    }

    throw new ExitException(exitCode);
  }

  @Override
  public final void run () {
    try {
      processArguments(programArguments);
      runProgram();
    } catch (ProgramException exception) {
      onProgramException(exception);
    }
  }
}
