// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_LINE_INPUT_MODAL_LINE_INPUT_H_
#define SRC_LIB_LINE_INPUT_MODAL_LINE_INPUT_H_

#include "lib/fit/function.h"
#include "src/lib/line_input/line_input.h"

namespace line_input {

struct ModalPromptOptions {
  // When set, requires that the user press enter after typing. Otherwise, if the user has typed
  // an input that matches one of the options it will be implicitly accepted. Implicit enter
  // normally only makes sense for single-letter input ("y"/"n" type things).
  bool require_enter = true;

  // Compares a lower-case version of the user input to the option values. The option values must
  // be lower-case for this to work. The lower-cased version of the input will be passed to the
  // accept callback.
  bool case_sensitive = false;

  // Possible valid options that will cause the prompt to accept the input. If accepting case
  // insensitive input, these should be lower-case.
  std::vector<std::string> options;

  // When nonempty, this string input will be sent when control-C is pressed. This provides a way
  // for the caller to specify the behavior of Control-C without having another code path.
  //
  // This should be one of the |options| strings. It will be passed unvalidated to the callback.
  std::string cancel_option;
};

// Manages multiple line input objects to manage regular input and temporary modal input for
// questions. This is a base class, it delegates to a derived class to provide the line editor
// implementations for different I/O schemes.
class ModalLineInput : public LineInput {
 public:
  using Factory = std::function<std::unique_ptr<LineInput>(AcceptCallback accept_cb,
                                                           const std::string& prompt)>;

  // In response to this callback, the implementation should call EndModal() if modal input is
  // complete.
  using ModalCompletionCallback = fit::function<void(const std::string&)>;

  // Callback that the modal input is about to be shown. In the normal case where there is no
  // current modal prompt open, it will be called immediately from BeginModal(). But implementing
  // this allows the embedder to properly handle the nested modal prompt case.
  //
  // It is expected that embedders will use this to display text that would go above the modal
  // prompt.
  using WillShowModalCallback = fit::callback<void()>;

  // The constructor takes a factory function for the underlying LineInput types. These are used
  // to actually get input for the normal case and the modal input case. By default (null factory
  // function), a "stdout" line input will be used which is the expected behavior. Replacing the
  // line input implementation allows tests to use this class without using stdout.
  //
  // Must call Init() before using any functions.
  explicit ModalLineInput(Factory factory = Factory());
  virtual ~ModalLineInput() = default;

  // This can't be in the constructor because it needs to call virtual functions.
  void Init(AcceptCallback accept_cb, const std::string& prompt);

  // LineInput implementation.
  void SetAutocompleteCallback(AutocompleteCallback cb) override;
  void SetChangeCallback(ChangeCallback cb) override;
  void SetCancelCallback(CancelCallback cb) override;
  void SetEofCallback(EofCallback cb) override;
  void SetMaxCols(size_t max) override;
  const std::string& GetLine() const override;
  const std::deque<std::string>& GetHistory() const override;
  void OnInput(char c) override;
  void AddToHistory(const std::string& line) override;
  void Hide(
      InterruptHandlingBehavior behavior = InterruptHandlingBehavior::kHandleInterrupts) override;
  void Show() override;
  void SetCurrentInput(const std::string& input) override;

  // Higher-level version of BeginModal() and EndModal() that takes a list of possible options and
  // will call the callback only when the user enters a match for one of the options. The completion
  // callback should not need to call EndModal(), it will be done automatically when a valid input
  // is selected.
  void ModalGetOption(const ModalPromptOptions& options, const std::string& prompt,
                      ModalCompletionCallback cb,
                      WillShowModalCallback will_show = WillShowModalCallback());

  // Begins a modal question with the given prompt. The normal prompt will be hidden and replaced
  // with the given one. The callback (see definition above for implementation requirements) will be
  // called when the user presses enter. This callback should call EndModal() if the input is
  // accepted.
  //
  // There can be multiple callbacks happening at the same time. If there is a current modal input
  // active at the time of this call, the new one will be added to a queue and will be shown when
  // when the modal prompts before it have been completed.
  //
  // The "will show" callback may be called from within this function (see its definition above).
  void BeginModal(const std::string& prompt, ModalCompletionCallback cb,
                  WillShowModalCallback will_show = WillShowModalCallback());

  // Closes the current modal entry. If there is another modal prompt in the queue, it will be
  // shown. If there is none, the normal prompt will be shown again.
  //
  // Normally this will be called from within the completion callback of BeginModal() when the
  // input is accepted.
  void EndModal();

 private:
  // Called when there is a modal dialog to show at the front of modal_callbacks_.
  //
  // The normal input should be hidden before this call.
  void ShowNextModal();

  std::unique_ptr<LineInput> MakeAndSetupLineInput(AcceptCallback accept_cb,
                                                   const std::string& prompt);

  // Guaranteed non-null.
  Factory factory_;

  std::unique_ptr<LineInput> normal_input_;
  std::unique_ptr<LineInput> modal_input_;

  // Old modal input that should be deleted in the next call to OnInput(). This allows us to avoid
  // deleting it from withinn its own call stack (normally EndModal() is called from within its
  // accept callback).
  std::unique_ptr<LineInput> to_delete_;

  LineInput* current_input_ = nullptr;  // Points to either the normal or modal input.

  int max_cols_ = 0;

  bool hidden_ = true;

  EofCallback eof_callback_;

  // Will be nonempty when a modal question is being asked. front() is the current callback, with
  // later requests going toward the back().
  struct ModalRecord {
    std::string prompt;
    ModalCompletionCallback complete;
    WillShowModalCallback will_show;
  };
  std::deque<ModalRecord> modal_callbacks_;
};

}  // namespace line_input

#endif  // SRC_LIB_LINE_INPUT_MODAL_LINE_INPUT_H_
