// 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.

#include "src/lib/line_input/modal_line_input.h"

#include <optional>

#include <gtest/gtest.h>

#include "src/lib/line_input/test_line_input.h"

namespace line_input {

namespace {

class TestModalLineInput : public ModalLineInput {
 public:
  TestModalLineInput() : ModalLineInput() {}
  ~TestModalLineInput() override {}

 protected:
  std::unique_ptr<LineInput> MakeLineInput(AcceptCallback accept_cb,
                                           const std::string& prompt) override {
    return std::make_unique<TestLineInput>(prompt, std::move(accept_cb));
  }
};

}  // namespace

// Runs two asynchronous modal prompts and makes sure they each run in sequence.
TEST(ModalLineInputTest, Nested) {
  std::optional<std::string> accept_line;

  TestModalLineInput input;
  input.Init([&accept_line](const std::string& line) { accept_line = line; }, "Prompt ");
  input.Show();

  // Send some regular input.
  input.OnInput('a');
  input.OnInput('b');

  // Start a modal prompt. The input "x" keeps it open, "m1" closes it.
  bool got_prompt_1 = false;
  input.BeginModal("Modal1 ", [&input, &got_prompt_1](const std::string& line) {
    got_prompt_1 = true;
    EXPECT_TRUE(line == "x" || line == "m1");
    if (line == "m1")
      input.EndModal();
  });

  // Start a second modal prompt before the first one is accepted.
  bool got_prompt_2 = false;
  input.BeginModal("Modal1 ", [&input, &got_prompt_2](const std::string& line) {
    got_prompt_2 = true;
    EXPECT_EQ("m2", line);
    input.EndModal();
  });

  // Input should now go to the modal promot #1.
  input.OnInput('x');
  input.OnInput('\r');
  EXPECT_TRUE(got_prompt_1);

  // That input should keep it open and read another line.
  got_prompt_1 = false;
  input.OnInput('m');
  input.OnInput('1');
  input.OnInput('\r');
  EXPECT_TRUE(got_prompt_1);

  // It should now switch to the second modal prompt.
  input.OnInput('m');
  input.OnInput('2');
  input.OnInput('\r');
  EXPECT_TRUE(got_prompt_2);

  // Further input should go to the regular prompt.
  input.OnInput('c');
  input.OnInput('\r');

  // The original + new input should be there.
  EXPECT_EQ("abc", accept_line);
}

TEST(ModalLineInputTest, ModalGetOption) {
  TestModalLineInput input;
  std::optional<std::string> read_line;  // Last non-modal result.
  input.Init([&read_line](const std::string& line) { read_line = line; }, "Prompt ");
  input.Show();

  ModalPromptOptions options;
  options.require_enter = true;
  options.case_sensitive = true;
  options.options.push_back("y");
  options.options.push_back("n");

  std::string result;
  input.ModalGetOption(options, ">", [&result](const std::string& line) { result = line; });

  // Empty input should get rejected.
  input.OnInput('\r');
  EXPECT_TRUE(result.empty());

  // Invalid input should get rejected.
  input.OnInput('X');
  input.OnInput('\r');
  EXPECT_TRUE(result.empty());

  // It was marked case-sensitive so uppercase should be rejected.
  input.OnInput('Y');
  input.OnInput('\r');
  EXPECT_TRUE(result.empty());

  // It was marked case-sensitive so uppercase should be rejected.
  input.OnInput('y');
  EXPECT_TRUE(result.empty());  // Because enter was marked required.
  input.OnInput('\r');
  ASSERT_EQ("y", result);

  // Should have gone back to normal mode.
  input.OnInput('z');
  input.OnInput('\r');
  ASSERT_TRUE(read_line);
  EXPECT_EQ("z", *read_line);

  // Now try one with the opposite options.
  options.require_enter = false;
  options.case_sensitive = false;
  result.clear();
  input.ModalGetOption(options, ">", [&result](const std::string& line) { result = line; });

  // Invalid input should still be rejected.
  input.OnInput('X');
  input.OnInput('\r');
  EXPECT_TRUE(result.empty());

  // Case-insensitive uppercase should implicitly accept with new newline required.
  input.OnInput('Y');
  ASSERT_EQ("y", result);  // Result should be lower-cased.

  // Should have gone back to normal mode.
  read_line = std::nullopt;
  input.OnInput('y');
  input.OnInput('\r');
  ASSERT_TRUE(read_line);
  EXPECT_EQ("y", *read_line);

  // Control-C will normally do nothing.
  result.clear();
  input.ModalGetOption(options, ">", [&result](const std::string& line) { result = line; });
  input.OnInput('a');
  input.OnInput(SpecialCharacters::kKeyControlC);
  EXPECT_TRUE(result.empty());
  input.OnInput(SpecialCharacters::kKeyBackspace);
  input.OnInput('y');
  EXPECT_EQ("y", result);

  // Setting a cancel response will make it return that.
  result.clear();
  options.cancel_option = "n";
  input.ModalGetOption(options, ">", [&result](const std::string& line) { result = line; });
  input.OnInput(SpecialCharacters::kKeyControlC);
  EXPECT_EQ("n", result);
}

}  // namespace line_input
