// Copyright (C) 2009 The Android Open Source Project
//
// 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 com.google.gerrit.pgm.init.api;

import com.google.errorprone.annotations.FormatMethod;
import com.google.errorprone.annotations.FormatString;
import com.google.gerrit.common.Die;
import com.google.gerrit.common.Nullable;
import java.io.Console;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;

/** Console based interaction with the invoking user. */
public abstract class ConsoleUI {
  /** Get a UI instance, assuming interactive mode. */
  public static ConsoleUI getInstance() {
    return getInstance(false);
  }

  /** Get a UI instance, possibly forcing batch mode. */
  public static ConsoleUI getInstance(boolean batchMode) {
    Console console = batchMode ? null : System.console();
    return console != null ? new Interactive(console) : new Batch();
  }

  /** Constructs an exception indicating the user aborted the operation. */
  protected static Die abort() {
    return new Die("aborted by user");
  }

  /** Returns true if this is a batch UI that has no user interaction. */
  public abstract boolean isBatch();

  /** Display a header message before a series of prompts. */
  public abstract void header(String fmt, Object... args);

  /** Display a message. */
  public abstract void message(String fmt, Object... args);

  /** Request the user to answer a yes/no question. */
  public abstract boolean yesno(Boolean def, String fmt, Object... args);

  /** Prints a message asking the user to let us know when its safe to continue. */
  public abstract void waitForUser();

  /** Prompt the user for a string, suggesting a default, and returning choice. */
  public abstract String readString(String def, String fmt, Object... args);

  /** Prompt the user to make a choice from an allowed list of values. */
  public abstract String readString(
      String def, Set<String> allowedValues, String fmt, Object... args);

  /** Prompt the user for an integer value, suggesting a default. */
  public int readInt(int def, String fmt, Object... args) {
    for (; ; ) {
      String p = readString(String.valueOf(def), fmt, args);
      try {
        return Integer.parseInt(p.trim(), 10);
      } catch (NumberFormatException e) {
        System.err.println("error: Invalid integer format: " + p.trim());
      }
    }
  }

  /** Prompt the user for a password, returning the string; null if blank. */
  public abstract String password(String fmt, Object... args);

  /** Display an error message on the system stderr. */
  @FormatMethod
  public void error(String format, Object... args) {
    System.err.println(String.format(format, args));
    System.err.flush();
  }

  /** Prompt the user to make a choice from an enumeration's values. */
  public abstract <T extends Enum<?>, A extends EnumSet<? extends T>> T readEnum(
      T def, A options, String fmt, Object... args);

  private static class Interactive extends ConsoleUI {
    private final Console console;

    Interactive(Console console) {
      this.console = console;
    }

    @Override
    public boolean isBatch() {
      return false;
    }

    @Override
    @FormatMethod
    public boolean yesno(Boolean def, String fmt, Object... args) {
      final String prompt = String.format(fmt, args);
      for (; ; ) {
        String y = "y";
        String n = "n";
        if (def != null) {
          if (def) {
            y = "Y";
          } else {
            n = "N";
          }
        }

        String yn = console.readLine("%-30s [%s/%s]? ", prompt, y, n);
        if (yn == null) {
          throw abort();
        }
        yn = yn.trim();
        if (def != null && yn.isEmpty()) {
          return def;
        }
        if (yn.equalsIgnoreCase("y") || yn.equalsIgnoreCase("yes")) {
          return true;
        }
        if (yn.equalsIgnoreCase("n") || yn.equalsIgnoreCase("no")) {
          return false;
        }
      }
    }

    @Override
    public void waitForUser() {
      if (console.readLine("Press enter to continue ") == null) {
        throw abort();
      }
    }

    @Override
    @FormatMethod
    public String readString(String def, @FormatString String fmt, Object... args) {
      final String prompt = String.format(fmt, args);
      String r;
      if (def != null) {
        r = console.readLine("%-30s [%s]: ", prompt, def);
      } else {
        r = console.readLine("%-30s : ", prompt);
      }
      if (r == null) {
        throw abort();
      }
      r = r.trim();
      if (r.isEmpty()) {
        return def;
      }
      return r;
    }

    @Override
    @FormatMethod
    public String readString(
        String def, Set<String> allowedValues, @FormatString String fmt, Object... args) {
      for (; ; ) {
        String r = readString(def, fmt, args);
        if (allowedValues.contains(r.toLowerCase(Locale.US))) {
          return r.toLowerCase(Locale.US);
        }
        if (!"?".equals(r)) {
          console.printf("error: '%s' is not a valid choice\n", r);
        }
        console.printf("       Supported options are:\n");
        for (String v : allowedValues) {
          console.printf("         %s\n", v.toLowerCase(Locale.US));
        }
      }
    }

    @Override
    @FormatMethod
    @Nullable
    public String password(String fmt, Object... args) {
      final String prompt = String.format(fmt, args);
      for (; ; ) {
        final char[] a1 = console.readPassword("%-30s : ", prompt);
        if (a1 == null) {
          throw abort();
        }

        final char[] a2 = console.readPassword("%30s : ", "confirm password");
        if (a2 == null) {
          throw abort();
        }

        final String s1 = new String(a1);
        final String s2 = new String(a2);
        if (!s1.equals(s2)) {
          console.printf("error: Passwords did not match; try again\n");
          continue;
        }
        return !s1.isEmpty() ? s1 : null;
      }
    }

    @Override
    @FormatMethod
    public <T extends Enum<?>, A extends EnumSet<? extends T>> T readEnum(
        T def, A options, String fmt, Object... args) {
      final String prompt = String.format(fmt, args);
      for (; ; ) {
        String r =
            console.readLine("%-30s [%s/?]: ", prompt, def.toString().toLowerCase(Locale.US));
        if (r == null) {
          throw abort();
        }
        r = r.trim();
        if (r.isEmpty()) {
          return def;
        }
        for (T e : options) {
          if (e.toString().equalsIgnoreCase(r)) {
            return e;
          }
        }
        if (!"?".equals(r)) {
          console.printf("error: '%s' is not a valid choice\n", r);
        }
        console.printf("       Supported options are:\n");
        for (T e : options) {
          console.printf("         %s\n", e.toString().toLowerCase(Locale.US));
        }
      }
    }

    @Override
    public void header(String fmt, Object... args) {
      fmt = fmt.replace("\n", "\n*** ");
      console.printf("\n*** " + fmt + "\n*** \n\n", args);
    }

    @Override
    public void message(String fmt, Object... args) {
      console.printf(fmt, args);
    }
  }

  private static class Batch extends ConsoleUI {
    @Override
    public boolean isBatch() {
      return true;
    }

    @Override
    public boolean yesno(Boolean def, String fmt, Object... args) {
      return def != null ? def : true;
    }

    @Override
    public String readString(String def, String fmt, Object... args) {
      return def;
    }

    @Override
    public String readString(String def, Set<String> allowedValues, String fmt, Object... args) {
      return def;
    }

    @Override
    public void waitForUser() {}

    @Override
    public String password(String fmt, Object... args) {
      return null;
    }

    @Override
    public <T extends Enum<?>, A extends EnumSet<? extends T>> T readEnum(
        T def, A options, String fmt, Object... args) {
      return def;
    }

    @Override
    public void header(String fmt, Object... args) {}

    @Override
    public void message(String fmt, Object... args) {}
  }
}
