// Copyright 2020 The Chromium OS 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 <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "minios/key_reader.h"

using testing::_;

namespace minios {

class KeyReaderTest : public ::testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    test_root_ = temp_dir_.GetPath();
    ASSERT_TRUE(base::CreateDirectory(
        base::FilePath(test_root_).Append("usr/share/misc")));
    ev_.value = 0;
  }
  struct input_event ev_;
  // Test directory.
  base::ScopedTempDir temp_dir_;
  base::FilePath test_root_;
};

class MockKeyReader : public KeyReader {
 public:
  MockKeyReader() : KeyReader(true) {}
  explicit MockKeyReader(bool include_usb) : KeyReader(include_usb) {}
  MockKeyReader(bool include_usb, std::string country_code)
      : KeyReader(include_usb, country_code) {}
  MOCK_METHOD(bool, GetEpEvent, (int epfd, struct input_event* ev, int* index));
  MOCK_METHOD(bool, GetValidFds, (bool check_supported_keys));
  MOCK_METHOD(bool, EpollCreate, (base::ScopedFD * epfd));
};

class MockDelegate : public KeyReader::Delegate {
 public:
  MOCK_METHOD(void, OnKeyPress, (int, int, bool));
};

TEST_F(KeyReaderTest, BasicKeyTest) {
  KeyReader key_reader(true, "us");
  EXPECT_TRUE(key_reader.SetKeyboardContext());
  // Test Basic Numbers.
  ev_.code = 2;
  key_reader.GetCharForTest(ev_);

  ev_.code = 4;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Test capitalization and special characters.
  // Left shift key down.
  ev_.code = 42;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.code = 16;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13Q", key_reader.GetUserInputForTest());

  ev_.code = 17;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13QW", key_reader.GetUserInputForTest());

  ev_.code = 3;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13QW@", key_reader.GetUserInputForTest());

  // Left shit key release.
  ev_.code = 42;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);

  // No longer capitalized or special.
  ev_.code = 18;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13QW@e", key_reader.GetUserInputForTest());

  ev_.code = 3;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13QW@e2", key_reader.GetUserInputForTest());
}

TEST_F(KeyReaderTest, PrintableKeyTest) {
  KeyReader key_reader(true, "us");
  EXPECT_TRUE(key_reader.SetKeyboardContext());

  ev_.code = 2;
  key_reader.GetCharForTest(ev_);

  ev_.code = 4;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Non-alphanumeric keys should not affect input length.
  // Left Shift.
  ev_.code = 42;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Escape.
  ev_.code = 1;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Left Alt.
  ev_.code = 56;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Tab.
  ev_.code = 15;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Ctrl.
  ev_.code = 29;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("13", key_reader.GetUserInputForTest());

  // Continue taking in input.
  ev_.code = 3;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("132", key_reader.GetUserInputForTest());

  // Space bar.
  ev_.code = 57;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("132 ", key_reader.GetUserInputForTest());
}

TEST_F(KeyReaderTest, InputLengthTest) {
  KeyReader key_reader(true, "us");
  EXPECT_TRUE(key_reader.SetKeyboardContext());

  // Add max input chars.
  ev_.code = 52;
  for (int i = 0; i < kMaxInputLength; i++) {
    key_reader.GetCharForTest(ev_);
  }

  EXPECT_EQ(std::string(kMaxInputLength, '.'),
            key_reader.GetUserInputForTest());

  // Cannot add past kMaxInputLength.
  ev_.code = 3;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ(std::string(kMaxInputLength, '.'),
            key_reader.GetUserInputForTest());

  // Test backspace. individual key press.
  ev_.code = 14;
  for (int i = 0; i < 20; i++) {
    key_reader.GetCharForTest(ev_);
  }

  EXPECT_EQ(std::string(kMaxInputLength - 20, '.'),
            key_reader.GetUserInputForTest());

  // Back space repeated keypress.
  // Stop deleting when string empty.
  ev_.value = 2;
  int remaining_chars = kRepeatedSensitivity * (kMaxInputLength - 20);
  for (int i = 0; i < remaining_chars + 2; i++) {
    key_reader.GetCharForTest(ev_);
  }

  EXPECT_EQ("", key_reader.GetUserInputForTest());
}

TEST_F(KeyReaderTest, ReturnKeyTest) {
  KeyReader key_reader(true, "us");
  EXPECT_TRUE(key_reader.SetKeyboardContext());

  // Return key press should return true.

  ev_.code = 28;
  EXPECT_TRUE(key_reader.GetCharForTest(ev_));

  ev_.code = 16;
  ev_.value = 0;
  for (int i = 0; i < 5; i++) {
    key_reader.GetCharForTest(ev_);
  }
  EXPECT_EQ("qqqqq", key_reader.GetUserInputForTest());

  ev_.code = 28;
  EXPECT_TRUE(key_reader.GetCharForTest(ev_));
}

TEST_F(KeyReaderTest, FrenchKeyTest) {
  KeyReader key_reader(true, "fr");
  EXPECT_TRUE(key_reader.SetKeyboardContext());

  ev_.code = 16;
  key_reader.GetCharForTest(ev_);

  ev_.code = 17;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az", key_reader.GetUserInputForTest());

  ev_.code = 4;
  key_reader.GetCharForTest(ev_);
  ev_.code = 5;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az\"'", key_reader.GetUserInputForTest());

  // Not a printable ASCII (accent aigu), do not add to input.
  ev_.code = 8;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az\"'", key_reader.GetUserInputForTest());

  // Test capitalization and special characters.
  // Left shift key down.
  ev_.code = 42;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.value = 0;
  ev_.code = 17;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az\"'Z", key_reader.GetUserInputForTest());

  ev_.code = 4;
  key_reader.GetCharForTest(ev_);
  ev_.code = 5;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az\"'Z34", key_reader.GetUserInputForTest());

  ev_.code = 42;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);

  // Get third char on key.
  // ALTGR (right alt) + CTL key press.

  ev_.code = 29;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.code = 100;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.code = 4;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("az\"'Z34#", key_reader.GetUserInputForTest());
}

TEST_F(KeyReaderTest, JapaneseKeyTest) {
  KeyReader key_reader(true, "jp");
  EXPECT_TRUE(key_reader.SetKeyboardContext());

  ev_.code = 16;
  key_reader.GetCharForTest(ev_);

  ev_.code = 17;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("qw", key_reader.GetUserInputForTest());

  ev_.code = 42;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.value = 0;
  ev_.code = 4;
  key_reader.GetCharForTest(ev_);
  ev_.code = 5;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("qw#$", key_reader.GetUserInputForTest());

  // Test capitalization and special characters.
  // Left shift key down.
  ev_.code = 42;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.value = 0;
  ev_.code = 17;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("qw#$W", key_reader.GetUserInputForTest());

  ev_.code = 42;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);

  // Get third char on key.
  // ALT + CTL key press.

  ev_.code = 29;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  ev_.code = 56;
  ev_.value = 1;
  key_reader.GetCharForTest(ev_);

  // Japanese character should not be added to input.
  ev_.code = 16;
  ev_.value = 0;
  key_reader.GetCharForTest(ev_);
  EXPECT_EQ("qw#$W", key_reader.GetUserInputForTest());
}

TEST_F(KeyReaderTest, OnlyEvWaitKeyFunction) {
  MockKeyReader key_reader;
  // Cannot access password functions.
  EXPECT_FALSE(key_reader.InputSetUp());
}

TEST_F(KeyReaderTest, OnlyEvWaitKeyFunctionFalse) {
  MockKeyReader key_reader(false);
  // Cannot access password functions when include usb is false.
  EXPECT_FALSE(key_reader.InputSetUp());
}

TEST_F(KeyReaderTest, GetUserInputTab) {
  MockKeyReader key_reader(false, "us");
  EXPECT_CALL(key_reader, GetValidFds(false)).WillOnce(testing::Return(true));
  EXPECT_CALL(key_reader, EpollCreate(_)).WillOnce(testing::Return(true));
  // Tab key release recorded
  struct input_event ev_release {
    .type = EV_KEY, .code = 15, .value = 0,
  };
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillOnce(testing::DoAll(testing::SetArgPointee<1>(ev_release),
                               testing::Return(true)));

  bool enter, tab = false;
  std::string input;

  EXPECT_TRUE(key_reader.InputSetUp());
  EXPECT_TRUE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_TRUE(tab);
  EXPECT_TRUE(input.empty());
}

TEST_F(KeyReaderTest, GetUserInputEnter) {
  MockKeyReader key_reader(false, "us");
  testing::InSequence s;
  EXPECT_CALL(key_reader, GetValidFds(false)).WillOnce(testing::Return(true));
  EXPECT_CALL(key_reader, EpollCreate(_)).WillOnce(testing::Return(true));
  // Enter key release recorded.
  struct input_event ev_release {
    .type = EV_KEY, .code = 28, .value = 1,
  };
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillOnce(testing::DoAll(testing::SetArgPointee<1>(ev_release),
                               testing::Return(true)));

  ev_release.value = 0;
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillOnce(testing::DoAll(testing::SetArgPointee<1>(ev_release),
                               testing::Return(true)));

  bool enter, tab = false;
  std::string input;

  EXPECT_TRUE(key_reader.InputSetUp());
  // Record enter press and release key events.
  EXPECT_TRUE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_TRUE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_TRUE(enter);
  EXPECT_TRUE(input.empty());
}

TEST_F(KeyReaderTest, GetUserInputError) {
  MockKeyReader key_reader(false, "us");

  EXPECT_CALL(key_reader, GetValidFds(false)).WillOnce(testing::Return(true));
  EXPECT_CALL(key_reader, EpollCreate(_)).WillOnce(testing::Return(true));

  EXPECT_CALL(key_reader, GetEpEvent(_, _, _)).WillOnce(testing::Return(false));

  bool enter, tab;
  std::string input;

  EXPECT_TRUE(key_reader.InputSetUp());
  EXPECT_FALSE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_TRUE(input.empty());
}

TEST_F(KeyReaderTest, GetUserInputGetChar) {
  MockKeyReader key_reader(false, "us");
  EXPECT_CALL(key_reader, GetValidFds(false)).WillOnce(testing::Return(true));
  EXPECT_CALL(key_reader, EpollCreate(_)).WillOnce(testing::Return(true));
  // A-key release recorded.
  struct input_event ev_release {
    .type = EV_KEY, .code = 30, .value = 0,
  };
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillOnce(testing::DoAll(testing::SetArgPointee<1>(ev_release),
                               testing::Return(true)));

  bool enter, tab;
  std::string input;

  // Check keyboard input multiple chars.
  EXPECT_TRUE(key_reader.InputSetUp());
  EXPECT_TRUE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_EQ("a", input);

  // P-key release recorded.
  ev_release.code = 25;
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillOnce(testing::DoAll(testing::SetArgPointee<1>(ev_release),
                               testing::Return(true)));

  EXPECT_TRUE(key_reader.GetUserInput(&enter, &tab, &input));
  EXPECT_EQ("ap", input);
}

TEST_F(KeyReaderTest, InitFdFailure) {
  MockKeyReader key_reader(false);
  EXPECT_CALL(key_reader, GetValidFds(true)).WillOnce(testing::Return(false));
  EXPECT_FALSE(key_reader.Init({103, 108, 28}));
}

TEST_F(KeyReaderTest, InitEpollFailure) {
  MockKeyReader key_reader(false);
  EXPECT_CALL(key_reader, GetValidFds(true)).WillOnce(testing::Return(true));
  EXPECT_CALL(key_reader, EpollCreate(_)).WillOnce(testing::Return(false));
  EXPECT_FALSE(key_reader.Init({103, 108, 28}));
}

TEST_F(KeyReaderTest, OnKeyEventRepeat) {
  MockKeyReader key_reader(false, "us");
  MockDelegate delegate;

  // Key repeat event.
  struct input_event ev_repeat {
    .type = EV_KEY, .code = KEY_ENTER, .value = 2,
  };
  EXPECT_CALL(key_reader, GetEpEvent(_, _, _))
      .WillRepeatedly(testing::DoAll(testing::SetArgPointee<1>(ev_repeat),
                                     testing::Return(true)));

  int num_repeats = 5;
  EXPECT_CALL(delegate, OnKeyPress(_, _, false)).Times(num_repeats);
  EXPECT_CALL(delegate, OnKeyPress(_, _, true)).Times(num_repeats);

  key_reader.keys_ = {KEY_UP, KEY_DOWN, KEY_ENTER, KEY_ESC};
  key_reader.SetDelegate(&delegate);
  // Repeated key press.
  for (int i = 0; i < num_repeats * kRepeatedSensitivity; ++i)
    key_reader.OnKeyEvent();
}

}  // namespace minios
