// Copyright 2018 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_LINE_INPUT_H_
#define SRC_LIB_LINE_INPUT_LINE_INPUT_H_

#include <deque>
#include <string>
#include <vector>

#include "lib/fit/function.h"

#if !defined(__Fuchsia__)
struct termios;
#endif

namespace line_input {

struct SpecialCharacters {
  static constexpr char kKeyControlA = 1;
  static constexpr char kKeyControlB = 2;
  static constexpr char kKeyControlD = 4;
  static constexpr char kKeyControlE = 5;
  static constexpr char kKeyControlF = 6;
  static constexpr char kKeyControlH = 8;
  static constexpr char kKeyTab = 9;
  static constexpr char kKeyNewline = 10;
  static constexpr char kKeyFormFeed = 12;
  static constexpr char kKeyEnter = 13;
  static constexpr char kKeyControlN = 14;
  static constexpr char kKeyControlP = 16;
  static constexpr char kKeyControlU = 21;
  static constexpr char kKeyControlW = 23;
  static constexpr char kKeyEsc = 27;
  static constexpr char kKeyBackspace = 127;

  // Escape sequences for terminal output.
  static const char* kTermBeginningOfLine;
  static const char* kTermClearToEnd;
  static const char* kTermCursorToColFormat;  // printf format.
};

// This class implements a push model for input of characters, allowing it to
// be used in asynchronous contexts.
//
// The model is you create a LineInput class outside of the input loop. It
// encapsulates the history state and remembers the prompt. When you want to
// read a line:
//
//  1. Call BeginReadLine().
//  2. Push data to it via OnInput() until it returns true.
//  3. Get the input from line().
//  4. Add line to history if desired.
//  5. Repeat.
class LineInputBase {
 public:
  // Given some typing, returns a prioritized list of completions.
  using CompletionCallback = fit::function<std::vector<std::string>(const std::string&)>;

  explicit LineInputBase(const std::string& prompt);
  virtual ~LineInputBase();

  // The column width of the screen before horizontal scrolling. If 0,
  // scrolling will be disabled.
  void set_max_cols(size_t max) { max_cols_ = max; }

  // The completion callback provides suggestions for tab completion. When
  // unset, tab completion will be disabled.
  void set_completion_callback(CompletionCallback cc) { completion_callback_ = std::move(cc); }

  // Returns the current line text.
  const std::string& line() const { return history_[history_index_]; }

  // Returns whether a Ctrl-D has been read.
  bool eof() const { return eof_; }

  // Returns the current insert position.
  size_t pos() const { return pos_; }

  const std::deque<std::string>& history() const { return history_; }

  // Call to initialize reading a new line.
  void BeginReadLine();

  // Provides one character of input to the editor. Returns true if the line
  // is complete (the user has pressed enter).
  bool OnInput(char c);

  // Adds the given line to history. If the history is longer than
  // max_history_, the oldest thing will be deleted.
  //
  // Only valid to be called before BeginReadLine() starts the next line input.
  void AddToHistory(const std::string& line);

  // The input can be hidden and re-shown. Hiding it will erase the current
  // line and put the cursor at the beginning of the line, but not change
  // any internal state. Showing it again will repaint the line at the new
  // cursor position. This allows other output to be printed to the screen
  // without interfering with the input.
  //
  // OnInput() should not be called while hidden.
  void Hide();
  void Show();

 protected:
  // Abstract output function, overridden by a derived class to output to
  // screen.
  virtual void Write(const std::string& data) = 0;

  // Enables and disables raw mode if applicable.
  virtual void EnsureRawMode() {}
  virtual void EnsureNoRawMode() {}

  // Helper to return the current line of text.
  std::string& cur_line() { return history_[history_index_]; }

  // Useful for testing.
  void set_pos(size_t pos) { pos_ = pos; }

 private:
  void HandleEscapedInput(char c);

  void HandleBackspace();
  void HandleDelete();
  void HandleFormFeed();
  void HandleEnter();
  void HandleTab();
  // NegAck is the name of Ctrl-U in ASCII world.
  void HandleNegAck();
  // EndOfTransimission is the name for Ctrl-W in ASCII world.
  void HandleEndOfTransimission();
  // EndOfFile means Ctrl-D with an empty input line.
  void HandleEndOfFile();

  void Insert(char c);
  void MoveLeft();
  void MoveRight();
  void MoveUp();
  void MoveDown();
  void MoveHome();
  void MoveEnd();

  void CancelCompletion();
  void AcceptCompletion();

  void RepaintLine();
  void ResetLineState();

  const std::string prompt_;
  size_t max_cols_ = 0;
  CompletionCallback completion_callback_;

  // Indicates whether the line is currently visible (as controlled by
  // Show()/Hide()).
  bool visible_ = true;

  // Indicates whether a line edit is in progress.
  bool editing_ = false;

  // Set to true once a Ctrl-D is read, indicating that the main loop should
  // exit.
  bool eof_ = false;

  // The history is basically the line stack going back in time as indices
  // increase. The currently viewed line is at [history_index_] and this is
  // where editing happens. When you start a new text entry, a new history
  // item is added and you delete it.
  //
  // This is simple but can be a bit confusing if you go back, edit, and then
  // press enter. The history item itself will be edited, and the same edited
  // version will be added again as the most recent history entry.
  //
  // This is weird because the editing has actually changed history. A more
  // complex model might be to maintain a virtual shadow copy of history that
  // you edit, and this shadow copy is replaced with the actual history
  // whenever you start editing a new line.
  std::deque<std::string> history_;  // front() is newest.
  size_t history_index_ = 0;         // Offset from history_.front().
  const size_t max_history_ = 256;

  bool completion_mode_ = false;
  std::vector<std::string> completions_;
  size_t completion_index_ = 0;

  // Tracks the current line's state before suggesting completions so we can
  // put them back if necessary. Only valid when completion_mode_ = true.
  std::string line_before_completion_;
  size_t pos_before_completion_;

  // When an escape is read, we enter "escaped input" mode which interprets the
  // next few characters input as an escape sequence.
  bool reading_escaped_input_ = false;
  std::string escape_sequence_;

  size_t pos_;  // Current editing position.
};

// Implementation of LineInput that prints to stdout. The caller is still
// responsible for providing input asynchronously. The initial width of the
// output will be automatically derived from the terminal associated with
// stdout (if any).
class LineInputStdout : public LineInputBase {
 public:
  LineInputStdout(const std::string& prompt);
  ~LineInputStdout() override;

  void EnsureRawMode() override;
  void EnsureNoRawMode() override;

 protected:
  void Write(const std::string& str) override;

 private:
#if !defined(__Fuchsia__)
  // The terminal is converted into raw mode when the prompt is visible and
  // accepting input. Then it's switched back. This block tracks that
  // information. Use unique_ptr to avoid bringing all terminal headers into
  // this header.
  bool raw_mode_enabled_ = false;
  std::unique_ptr<termios> raw_termios_;
  std::unique_ptr<termios> original_termios_;
#endif
};

// A blocking implementation that reads from stdin and writes to stdout.
class LineInputBlockingStdio : public LineInputStdout {
 public:
  LineInputBlockingStdio(const std::string& prompt);

  std::string ReadLine();
};

}  // namespace line_input

#endif  // SRC_LIB_LINE_INPUT_LINE_INPUT_H_
