/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stddef.h>
#include <stdio.h>

#include <functional>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/test_utils.h>
#include <gtest/gtest.h>

#include "common/test_constants.h"
#include "device.h"
#include "minui/minui.h"
#include "otautil/paths.h"
#include "private/resources.h"
#include "screen_ui.h"

static const std::vector<std::string> HEADERS{ "header" };
static const std::vector<std::string> ITEMS{ "item1", "item2", "item3", "item4", "1234567890" };

// TODO(xunchang) check if some draw functions are called when drawing menus.
class MockDrawFunctions : public DrawInterface {
  void SetColor(UIElement /* element */) const override {}
  void DrawHighlightBar(int /* x */, int /* y */, int /* width */,
                        int /* height */) const override {}
  int DrawHorizontalRule(int /* y */) const override {
    return 0;
  }
  int DrawTextLine(int /* x */, int /* y */, const std::string& /* line */,
                   bool /* bold */) const override {
    return 0;
  }
  void DrawSurface(const GRSurface* /* surface */, int /* sx */, int /* sy */, int /* w */,
                   int /* h */, int /* dx */, int /* dy */) const override {}
  void DrawFill(int /* x */, int /* y */, int /* w */, int /* h */) const override {}
  void DrawTextIcon(int /* x */, int /* y */, const GRSurface* /* surface */) const override {}
  int DrawTextLines(int /* x */, int /* y */,
                    const std::vector<std::string>& /* lines */) const override {
    return 0;
  }
  int DrawWrappedTextLines(int /* x */, int /* y */,
                           const std::vector<std::string>& /* lines */) const override {
    return 0;
  }
};

class ScreenUITest : public testing::Test {
 protected:
  MockDrawFunctions draw_funcs_;
};

// TODO(xunchang) Create a constructor.
static GRSurface CreateFakeGRSurface(int width, int height, int row_bytes, int pixel_bytes) {
  GRSurface fake_surface;
  fake_surface.width = width;
  fake_surface.height = height;
  fake_surface.row_bytes = row_bytes;
  fake_surface.pixel_bytes = pixel_bytes;

  return fake_surface;
}

TEST_F(ScreenUITest, StartPhoneMenuSmoke) {
  TextMenu menu(false, 10, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
  ASSERT_FALSE(menu.scrollable());
  ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
  ASSERT_EQ(5u, menu.ItemsCount());

  std::string message;
  ASSERT_FALSE(menu.ItemsOverflow(&message));
  for (size_t i = 0; i < menu.ItemsCount(); i++) {
    ASSERT_EQ(ITEMS[i], menu.TextItem(i));
  }

  ASSERT_EQ(0, menu.selection());
}

TEST_F(ScreenUITest, StartWearMenuSmoke) {
  TextMenu menu(true, 10, 8, HEADERS, ITEMS, 1, 20, draw_funcs_);
  ASSERT_TRUE(menu.scrollable());
  ASSERT_EQ(HEADERS[0], menu.text_headers()[0]);
  ASSERT_EQ(5u, menu.ItemsCount());

  std::string message;
  ASSERT_FALSE(menu.ItemsOverflow(&message));
  for (size_t i = 0; i < menu.ItemsCount() - 1; i++) {
    ASSERT_EQ(ITEMS[i], menu.TextItem(i));
  }
  // Test of the last item is truncated
  ASSERT_EQ("12345678", menu.TextItem(4));
  ASSERT_EQ(1, menu.selection());
}

TEST_F(ScreenUITest, StartPhoneMenuItemsOverflow) {
  TextMenu menu(false, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
  ASSERT_FALSE(menu.scrollable());
  ASSERT_EQ(1u, menu.ItemsCount());

  std::string message;
  ASSERT_FALSE(menu.ItemsOverflow(&message));
  for (size_t i = 0; i < menu.ItemsCount(); i++) {
    ASSERT_EQ(ITEMS[i], menu.TextItem(i));
  }

  ASSERT_EQ(0u, menu.MenuStart());
  ASSERT_EQ(1u, menu.MenuEnd());
}

TEST_F(ScreenUITest, StartWearMenuItemsOverflow) {
  TextMenu menu(true, 1, 20, HEADERS, ITEMS, 0, 20, draw_funcs_);
  ASSERT_TRUE(menu.scrollable());
  ASSERT_EQ(5u, menu.ItemsCount());

  std::string message;
  ASSERT_TRUE(menu.ItemsOverflow(&message));
  ASSERT_EQ("Current item: 1/5", message);

  for (size_t i = 0; i < menu.ItemsCount(); i++) {
    ASSERT_EQ(ITEMS[i], menu.TextItem(i));
  }

  ASSERT_EQ(0u, menu.MenuStart());
  ASSERT_EQ(1u, menu.MenuEnd());
}

TEST_F(ScreenUITest, PhoneMenuSelectSmoke) {
  int sel = 0;
  TextMenu menu(false, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
  // Mimic down button 10 times (2 * items size)
  for (int i = 0; i < 10; i++) {
    sel = menu.Select(++sel);
    ASSERT_EQ(sel, menu.selection());

    // Wraps the selection for unscrollable menu when it reaches the boundary.
    int expected = (i + 1) % 5;
    ASSERT_EQ(expected, menu.selection());

    ASSERT_EQ(0u, menu.MenuStart());
    ASSERT_EQ(5u, menu.MenuEnd());
  }

  // Mimic up button 10 times
  for (int i = 0; i < 10; i++) {
    sel = menu.Select(--sel);
    ASSERT_EQ(sel, menu.selection());

    int expected = (9 - i) % 5;
    ASSERT_EQ(expected, menu.selection());

    ASSERT_EQ(0u, menu.MenuStart());
    ASSERT_EQ(5u, menu.MenuEnd());
  }
}

TEST_F(ScreenUITest, WearMenuSelectSmoke) {
  int sel = 0;
  TextMenu menu(true, 10, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
  // Mimic pressing down button 10 times (2 * items size)
  for (int i = 0; i < 10; i++) {
    sel = menu.Select(++sel);
    ASSERT_EQ(sel, menu.selection());

    // Stops the selection at the boundary if the menu is scrollable.
    int expected = std::min(i + 1, 4);
    ASSERT_EQ(expected, menu.selection());

    ASSERT_EQ(0u, menu.MenuStart());
    ASSERT_EQ(5u, menu.MenuEnd());
  }

  // Mimic pressing up button 10 times
  for (int i = 0; i < 10; i++) {
    sel = menu.Select(--sel);
    ASSERT_EQ(sel, menu.selection());

    int expected = std::max(3 - i, 0);
    ASSERT_EQ(expected, menu.selection());

    ASSERT_EQ(0u, menu.MenuStart());
    ASSERT_EQ(5u, menu.MenuEnd());
  }
}

TEST_F(ScreenUITest, WearMenuSelectItemsOverflow) {
  int sel = 1;
  TextMenu menu(true, 3, 20, HEADERS, ITEMS, sel, 20, draw_funcs_);
  ASSERT_EQ(5u, menu.ItemsCount());

  // Scroll the menu to the end, and check the start & end of menu.
  for (int i = 0; i < 3; i++) {
    sel = menu.Select(++sel);
    ASSERT_EQ(i + 2, sel);
    ASSERT_EQ(static_cast<size_t>(i), menu.MenuStart());
    ASSERT_EQ(static_cast<size_t>(i + 3), menu.MenuEnd());
  }

  // Press down button one more time won't change the MenuStart() and MenuEnd().
  sel = menu.Select(++sel);
  ASSERT_EQ(4, sel);
  ASSERT_EQ(2u, menu.MenuStart());
  ASSERT_EQ(5u, menu.MenuEnd());

  // Scroll the menu to the top.
  // The expected menu sel, start & ends are:
  // sel 3, start 2, end 5
  // sel 2, start 2, end 5
  // sel 1, start 1, end 4
  // sel 0, start 0, end 3
  for (int i = 0; i < 4; i++) {
    sel = menu.Select(--sel);
    ASSERT_EQ(3 - i, sel);
    ASSERT_EQ(static_cast<size_t>(std::min(3 - i, 2)), menu.MenuStart());
    ASSERT_EQ(static_cast<size_t>(std::min(6 - i, 5)), menu.MenuEnd());
  }

  // Press up button one more time won't change the MenuStart() and MenuEnd().
  sel = menu.Select(--sel);
  ASSERT_EQ(0, sel);
  ASSERT_EQ(0u, menu.MenuStart());
  ASSERT_EQ(3u, menu.MenuEnd());
}

TEST_F(ScreenUITest, GraphicMenuSelection) {
  auto fake_surface = CreateFakeGRSurface(50, 50, 50, 1);
  std::vector<GRSurface*> items = { &fake_surface, &fake_surface, &fake_surface };
  GraphicMenu menu(&fake_surface, items, 0, draw_funcs_);

  ASSERT_EQ(0, menu.selection());

  int sel = 0;
  for (int i = 0; i < 3; i++) {
    sel = menu.Select(++sel);
    ASSERT_EQ((i + 1) % 3, sel);
    ASSERT_EQ(sel, menu.selection());
  }

  sel = 0;
  for (int i = 0; i < 3; i++) {
    sel = menu.Select(--sel);
    ASSERT_EQ(2 - i, sel);
    ASSERT_EQ(sel, menu.selection());
  }
}

TEST_F(ScreenUITest, GraphicMenuValidate) {
  auto fake_surface = CreateFakeGRSurface(50, 50, 50, 1);
  std::vector<GRSurface*> items = { &fake_surface, &fake_surface, &fake_surface };

  ASSERT_TRUE(GraphicMenu::Validate(200, 200, &fake_surface, items));

  // Menu exceeds the horizontal boundary.
  auto wide_surface = CreateFakeGRSurface(300, 50, 300, 1);
  ASSERT_FALSE(GraphicMenu::Validate(299, 200, &wide_surface, items));

  // Menu exceeds the vertical boundary.
  items.push_back(&fake_surface);
  ASSERT_FALSE(GraphicMenu::Validate(200, 249, &fake_surface, items));
}

static constexpr int kMagicAction = 101;

enum class KeyCode : int {
  TIMEOUT = -1,
  NO_OP = 0,
  UP = 1,
  DOWN = 2,
  ENTER = 3,
  MAGIC = 1001,
  LAST,
};

static const std::map<KeyCode, int> kKeyMapping{
  // clang-format off
  { KeyCode::NO_OP, Device::kNoAction },
  { KeyCode::UP, Device::kHighlightUp },
  { KeyCode::DOWN, Device::kHighlightDown },
  { KeyCode::ENTER, Device::kInvokeItem },
  { KeyCode::MAGIC, kMagicAction },
  // clang-format on
};

class TestableScreenRecoveryUI : public ScreenRecoveryUI {
 public:
  int WaitKey() override;

  void SetKeyBuffer(const std::vector<KeyCode>& buffer);

  int KeyHandler(int key, bool visible) const;

  // The following functions expose the protected members for test purpose.
  void RunLoadAnimation() {
    LoadAnimation();
  }

  size_t GetLoopFrames() const {
    return loop_frames;
  }

  size_t GetIntroFrames() const {
    return intro_frames;
  }

  bool GetRtlLocale() const {
    return rtl_locale_;
  }

 private:
  std::vector<KeyCode> key_buffer_;
  size_t key_buffer_index_;
};

void TestableScreenRecoveryUI::SetKeyBuffer(const std::vector<KeyCode>& buffer) {
  key_buffer_ = buffer;
  key_buffer_index_ = 0;
}

int TestableScreenRecoveryUI::KeyHandler(int key, bool) const {
  KeyCode key_code = static_cast<KeyCode>(key);
  if (kKeyMapping.find(key_code) != kKeyMapping.end()) {
    return kKeyMapping.at(key_code);
  }
  return Device::kNoAction;
}

int TestableScreenRecoveryUI::WaitKey() {
  if (IsKeyInterrupted()) {
    return static_cast<int>(RecoveryUI::KeyError::INTERRUPTED);
  }

  CHECK_LT(key_buffer_index_, key_buffer_.size());
  return static_cast<int>(key_buffer_[key_buffer_index_++]);
}

class ScreenRecoveryUITest : public ::testing::Test {
 protected:
  const std::string kTestLocale = "en-US";
  const std::string kTestRtlLocale = "ar";
  const std::string kTestRtlLocaleWithSuffix = "ar-EG";

  void SetUp() override {
    has_graphics_ = gr_init() == 0;
    gr_exit();

    if (has_graphics_) {
      ui_ = std::make_unique<TestableScreenRecoveryUI>();
    }

    testdata_dir_ = from_testdata_base("");
    Paths::Get().set_resource_dir(testdata_dir_);
    res_set_resource_dir(testdata_dir_);
  }

  bool has_graphics_;
  std::unique_ptr<TestableScreenRecoveryUI> ui_;
  std::string testdata_dir_;
};

#define RETURN_IF_NO_GRAPHICS                                                 \
  do {                                                                        \
    if (!has_graphics_) {                                                     \
      GTEST_LOG_(INFO) << "Test skipped due to no available graphics device"; \
      return;                                                                 \
    }                                                                         \
  } while (false)

TEST_F(ScreenRecoveryUITest, Init) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ASSERT_EQ(kTestLocale, ui_->GetLocale());
  ASSERT_FALSE(ui_->GetRtlLocale());
  ASSERT_FALSE(ui_->IsTextVisible());
  ASSERT_FALSE(ui_->WasTextEverVisible());
}

TEST_F(ScreenRecoveryUITest, dtor_NotCallingInit) {
  ui_.reset();
  ASSERT_FALSE(ui_);
}

TEST_F(ScreenRecoveryUITest, ShowText) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ASSERT_FALSE(ui_->IsTextVisible());
  ui_->ShowText(true);
  ASSERT_TRUE(ui_->IsTextVisible());
  ASSERT_TRUE(ui_->WasTextEverVisible());

  ui_->ShowText(false);
  ASSERT_FALSE(ui_->IsTextVisible());
  ASSERT_TRUE(ui_->WasTextEverVisible());
}

TEST_F(ScreenRecoveryUITest, RtlLocale) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestRtlLocale));
  ASSERT_TRUE(ui_->GetRtlLocale());
}

TEST_F(ScreenRecoveryUITest, RtlLocaleWithSuffix) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestRtlLocaleWithSuffix));
  ASSERT_TRUE(ui_->GetRtlLocale());
}

TEST_F(ScreenRecoveryUITest, ShowMenu) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ui_->SetKeyBuffer({
      KeyCode::UP,
      KeyCode::DOWN,
      KeyCode::UP,
      KeyCode::DOWN,
      KeyCode::ENTER,
  });
  ASSERT_EQ(3u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
                              std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                        std::placeholders::_1, std::placeholders::_2)));

  ui_->SetKeyBuffer({
      KeyCode::UP,
      KeyCode::UP,
      KeyCode::NO_OP,
      KeyCode::NO_OP,
      KeyCode::UP,
      KeyCode::ENTER,
  });
  ASSERT_EQ(2u, ui_->ShowMenu(HEADERS, ITEMS, 0, true,
                              std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                        std::placeholders::_1, std::placeholders::_2)));
}

TEST_F(ScreenRecoveryUITest, ShowMenu_NotMenuOnly) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ui_->SetKeyBuffer({
      KeyCode::MAGIC,
  });
  ASSERT_EQ(static_cast<size_t>(kMagicAction),
            ui_->ShowMenu(HEADERS, ITEMS, 3, false,
                          std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                    std::placeholders::_1, std::placeholders::_2)));
}

TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ui_->SetKeyBuffer({
      KeyCode::TIMEOUT,
  });
  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::TIMED_OUT),
            ui_->ShowMenu(HEADERS, ITEMS, 3, true, nullptr));
}

TEST_F(ScreenRecoveryUITest, ShowMenu_TimedOut_TextWasEverVisible) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ui_->ShowText(true);
  ui_->ShowText(false);
  ASSERT_TRUE(ui_->WasTextEverVisible());

  ui_->SetKeyBuffer({
      KeyCode::TIMEOUT,
      KeyCode::DOWN,
      KeyCode::ENTER,
  });
  ASSERT_EQ(4u, ui_->ShowMenu(HEADERS, ITEMS, 3, true,
                              std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                        std::placeholders::_1, std::placeholders::_2)));
}

TEST_F(ScreenRecoveryUITest, ShowMenuWithInterrupt) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  ui_->SetKeyBuffer({
      KeyCode::UP,
      KeyCode::DOWN,
      KeyCode::UP,
      KeyCode::DOWN,
      KeyCode::ENTER,
  });

  ui_->InterruptKey();
  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
            ui_->ShowMenu(HEADERS, ITEMS, 3, true,
                          std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                    std::placeholders::_1, std::placeholders::_2)));

  ui_->SetKeyBuffer({
      KeyCode::UP,
      KeyCode::UP,
      KeyCode::NO_OP,
      KeyCode::NO_OP,
      KeyCode::UP,
      KeyCode::ENTER,
  });
  ASSERT_EQ(static_cast<size_t>(RecoveryUI::KeyError::INTERRUPTED),
            ui_->ShowMenu(HEADERS, ITEMS, 0, true,
                          std::bind(&TestableScreenRecoveryUI::KeyHandler, ui_.get(),
                                    std::placeholders::_1, std::placeholders::_2)));
}

TEST_F(ScreenRecoveryUITest, LoadAnimation) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  // Make a few copies of loop00000.png from testdata.
  std::string image_data;
  ASSERT_TRUE(android::base::ReadFileToString(testdata_dir_ + "/loop00000.png", &image_data));

  std::vector<std::string> tempfiles;
  TemporaryDir resource_dir;
  for (const auto& name : { "00002", "00100", "00050" }) {
    tempfiles.push_back(android::base::StringPrintf("%s/loop%s.png", resource_dir.path, name));
    ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
  }
  for (const auto& name : { "00", "01" }) {
    tempfiles.push_back(android::base::StringPrintf("%s/intro%s.png", resource_dir.path, name));
    ASSERT_TRUE(android::base::WriteStringToFile(image_data, tempfiles.back()));
  }
  Paths::Get().set_resource_dir(resource_dir.path);

  ui_->RunLoadAnimation();

  ASSERT_EQ(2u, ui_->GetIntroFrames());
  ASSERT_EQ(3u, ui_->GetLoopFrames());

  for (const auto& name : tempfiles) {
    ASSERT_EQ(0, unlink(name.c_str()));
  }
}

TEST_F(ScreenRecoveryUITest, LoadAnimation_MissingAnimation) {
  RETURN_IF_NO_GRAPHICS;

  ASSERT_TRUE(ui_->Init(kTestLocale));
  // We need a dir that doesn't contain any animation. However, using TemporaryDir will give
  // leftovers since this is a death test where TemporaryDir::~TemporaryDir() won't be called.
  Paths::Get().set_resource_dir("/proc/self");

  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
  ASSERT_EXIT(ui_->RunLoadAnimation(), ::testing::KilledBySignal(SIGABRT), "");
}

#undef RETURN_IF_NO_GRAPHICS
