// 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() 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_
