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

#ifndef MINIOS_SCREENS_H_
#define MINIOS_SCREENS_H_

#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include <gtest/gtest_prod.h>

#include "minios/key_reader.h"
#include "minios/network_manager_interface.h"
#include "minios/process_manager.h"
#include "minios/screen_base.h"
#include "minios/update_engine_proxy.h"

namespace screens {

extern const char kScreens[];

// Dropdown Menu Colors.
extern const char kMenuDropdownFrameNavy[];
extern const char kMenuDropdownBackgroundBlack[];

// Key values.
extern const int kKeyUp;
extern const int kKeyDown;
extern const int kKeyEnter;
extern const int kKeyVolUp;
extern const int kKeyVolDown;
extern const int kKeyPower;

// Key state parameters.
extern const int kFdsMax;
extern const int kKeyMax;

// All the different screens in the MiniOs Flow. `kDownloadError` is shown when
// there is an Update Engine failure, `kNetworkError` is shown when there is an
// issue getting the networks. `kPasswordError` and `kConnectionError` are shown
// upon failures connecting to a chosen network.
enum class ScreenType {
  kWelcomeScreen = 0,
  kNetworkDropDownScreen = 1,
  kExpandedNetworkDropDownScreen = 2,
  kPasswordScreen = 3,
  kLanguageDropDownScreen = 4,
  kWaitForConnection = 5,
  kStartDownload = 6,
  kDownloadError = 7,
  kNetworkError = 8,
  kPasswordError = 9,
  kConnectionError = 10,
};

// Screens contains the different MiniOs Screens as well as specific components
// such as dropdowns and footers which are built using the pieces of
// ScreenBase.

class Screens : public ScreenBase,
                public key_reader::KeyReader::Delegate,
                public UpdateEngineProxy::UpdaterDelegate,
                public minios::NetworkManagerInterface::Observer {
 public:
  explicit Screens(
      ProcessManagerInterface* process_manager,
      std::shared_ptr<minios::NetworkManagerInterface> network_manager)
      : process_manager_(process_manager),
        network_manager_(network_manager),
        key_states_(kFdsMax, std::vector<bool>(kKeyMax, false)) {
    key_reader_.SetDelegate(this);
  }
  virtual ~Screens() = default;
  // Not copyable or movable.
  Screens(const Screens&) = delete;
  Screens& operator=(const Screens&) = delete;

  // Loads token constants for screen placement, checks whether locale is read
  // from right to left and whether device is detachable.
  bool Init();

  // Has the minimum needed to set up tests, to reduce excessive logging. All
  // other components are tested separately.
  bool InitForTest();

  // Shows the MiniOs Screens. Users can navigate between then using up/down
  // arrow keys.
  void StartMiniOsFlow();

  // Shows the list of all supported locales with the currently selected index
  // highlighted blue. Users can 'scroll' using the up and down arrow keys.
  void ShowLanguageDropdown();

  // Waits for key input and repaints the screen with a changed language
  // selection, clears the whole screen including the footer and updates the
  // language dependent constants. Returns to original screen after selection,
  virtual void LanguageMenuOnSelect();

  // Shows language menu drop down button on base screen. Button is highlighted
  // if it is currently selected.
  void ShowLanguageMenu(bool is_selected);

  // Shows footer with basic instructions and chromebook model.
  void ShowFooter();

  // Clears screen and shows footer and language drop down menu.
  void MessageBaseScreen();

  // Shows a list of all available networks.
  void ShowNetworkDropdown();

  // Shows network menu drop down button on the screen. Button is
  // highlighted if it is currently selected. Selecting this button directs to
  // the expanded network dropdown.
  void ShowCollapsedNetworkDropDown(bool is_selected);

  // Queries list of available networks and shows them as a drop down. On
  // selection sets the 'chosen_network' and redirects to the password
  // screen.
  void ExpandNetworkDropdown();

  // Get user password using the keyboard layout stored in locale. Users can use
  // the tab key to toggle showing the password.
  virtual void GetPassword();

  // Controls the flow of MiniOs by changing screen based on the current index
  // and screen and whether or not a button has been selected(entered). Called
  // every time a valid key press is recorded.
  void SwitchScreen(bool enter);

  // Getter and setter test functions for `index_` and `current_screen`.
  void SetIndexForTest(int index) { index_ = index; }
  int GetIndexForTest() { return index_; }
  void SetScreenForTest(ScreenType current_screen) {
    current_screen_ = current_screen;
  }
  ScreenType GetScreenForTest() { return current_screen_; }

  // Sets network list for test.
  void SetNetworkListForTest_(const std::vector<std::string>& networks) {
    network_list_ = networks;
  }

 private:
  FRIEND_TEST(ScreensTest, ReadDimension);
  FRIEND_TEST(ScreensTest, GetDimension);
  FRIEND_TEST(ScreensTest, GetLangConsts);
  FRIEND_TEST(ScreensTest, GetLangConstsError);
  FRIEND_TEST(ScreensTest, UpdateButtons);
  FRIEND_TEST(ScreensTest, UpdateButtonsIsDetachable);
  FRIEND_TEST(ScreensTest, CheckRightToLeft);
  FRIEND_TEST(ScreensTest, CheckDetachable);
  FRIEND_TEST(ScreensTest, GetVpdFromFile);
  FRIEND_TEST(ScreensTest, GetVpdFromCommand);
  FRIEND_TEST(ScreensTest, GetVpdFromDefault);
  FRIEND_TEST(ScreensTest, GetHwidFromCommand);
  FRIEND_TEST(ScreensTest, GetHwidFromDefault);
  FRIEND_TEST(ScreensTest, GetFreconConstFile);
  FRIEND_TEST(ScreensTest, GetFreconConstNoInt);
  FRIEND_TEST(ScreensTest, GetFreconConstNoFile);
  FRIEND_TEST(ScreensTest, MapRegionToKeyboardNoFile);
  FRIEND_TEST(ScreensTest, MapRegionToKeyboardNotDict);
  FRIEND_TEST(ScreensTest, MapRegionToKeyboardNoKeyboard);
  FRIEND_TEST(ScreensTest, MapRegionToKeyboardBadKeyboardFormat);
  FRIEND_TEST(ScreensTest, MapRegionToKeyboard);
  FRIEND_TEST(ScreensTestMocks, OnKeyPress);
  FRIEND_TEST(ScreensTestMocks, UpdateEngineError);
  FRIEND_TEST(ScreensTestMocks, UpdateEngineProgressComplete);
  FRIEND_TEST(ScreensTestMocks, IdleError);
  FRIEND_TEST(ScreensTestMocks, GetNetworks);
  FRIEND_TEST(ScreensTestMocks, OnConnectError);
  FRIEND_TEST(ScreensTestMocks, OnPasswordError);
  FRIEND_TEST(ScreensTestMocks, NoNetworksGiven);
  FRIEND_TEST(ScreensTestMocks, ScreenFlowForwardWithNetwork);
  FRIEND_TEST(ScreensTestMocks, GetNetworksRefresh);
  FRIEND_TEST(ScreensTestMocks, ChangeErrorScreen);
  FRIEND_TEST(ScreensTestMocks, ErrorScreenFallBack);

  // Changes the index and enter value based on the given key. Unknown keys are
  // ignored and index is kept within the range of menu items.
  void UpdateButtons(int menu_count, int key, bool* enter);

  // Read the language constants into memory. Does not change
  // based on the current locale. Returns false on failure.
  bool ReadLangConstants();

  // Sets the width of language token for a given locale. Returns false on
  // error.
  bool GetLangConstants(const std::string& locale, int* lang_width);

  // This function overloads Delegate. It is only called when the key is valid
  // and updates the key state for the given fd and key. Calls `SwitchState` to
  // update the flow once key is recorded as being pressed and released.
  void OnKeyPress(int fd_index, int key_changed, bool key_released) override;

  // `NetworkManagerInterface::Observer` overrides.
  // Updates the list of networks stored by the UI to show in the drop down.
  void OnGetNetworks(const std::vector<std::string>& networks,
                     brillo::Error* error) override;
  // Attempts to connect, shows error screen on failure.
  void OnConnect(const std::string& ssid, brillo::Error* error) override;

  // Calls `GetNetworks` to update the the list of networks.
  virtual void UpdateNetworkList();

  // Does all the reloading needed when the locale is changed, including
  // repainting the screen. Called after `LanguageDropdown` is done.
  virtual void OnLocaleChange();

  // Calls the show screen function of `current_screen`.
  virtual void ShowNewScreen();

  // Shows the buttons of MiniOs screens. Index changes button focus based on
  // button order.
  void ShowMiniOsWelcomeScreen();
  void ShowMiniOsNetworkDropdownScreen();
  void ShowMiniOsGetPasswordScreen();
  void ShowWaitingForConnectionScreen();
  void ShowMiniOsDownloadingScreen();
  virtual void ShowMiniOsCompleteScreen();

  // Checks whether the current language is read from right to left. Must be
  // updated every time the language changes.
  void CheckRightToLeft();

  // Checks whether device has a detachable keyboard and sets `is_detachable`.
  void CheckDetachable();

  // Get region from VPD. Set vpd_region_ to US as default.
  void GetVpdRegion();

  // Get hardware Id from crossystem. Set hwid to `CHROMEBOOK` as default.
  void ReadHardwareId();

  // Get XKB keyboard layout based on the VPD region. Return false on error.
  bool MapRegionToKeyboard(std::string* xkb_keyboard_layout);

  // Calls corresponding MiniOs screen based on update engine status. If UE is
  // `DOWNLOADING` then shows a progress bar with percentage.
  void OnProgressChanged(const update_engine::StatusResult& status) override;

  // Calls error screen components with different messages.
  void ShowErrorScreen(std::string error_message);

  // Reset and show error screen.
  void ChangeToErrorScreen(enum ScreenType error_screen);

  ProcessManagerInterface* process_manager_;

  key_reader::KeyReader key_reader_ =
      key_reader::KeyReader(/*include_usb=*/true);

  std::shared_ptr<minios::NetworkManagerInterface> network_manager_;

  // Whether the device has a detachable keyboard.
  bool is_detachable_{false};

  // Key value pairs that store language widths.
  base::StringPairs lang_constants_;

  // List of all supported locales.
  std::vector<std::string> supported_locales_;

  // List of currently available networks.
  std::vector<std::string> network_list_;

  // The networks the user has picked from the menu.
  std::string chosen_network_;

  // Hardware Id read from crossystem.
  std::string hwid_;

  // Region code read from VPD. Used to determine keyboard layout. Does not
  // change based on selected locale.
  std::string vpd_region_;

  // Records the key press for each fd and key, where the index of the fd is the
  // row and the key code the column. Resets to false after key is released.
  // Only tracks the valid keys.
  std::vector<std::vector<bool>> key_states_;

  // The number of menu buttons on each screen corresponding to the enum
  // numbers, used to keep the index in bounds. The drop down screen counts are
  // updated later based on the locale and network lists.
  std::unordered_map<ScreenType, int> menu_count_{
      {ScreenType::kWelcomeScreen, 3},
      {ScreenType::kNetworkDropDownScreen, 3},
      {ScreenType::kExpandedNetworkDropDownScreen, 0},
      {ScreenType::kPasswordScreen, 3},
      {ScreenType::kLanguageDropDownScreen, 0},
      {ScreenType::kWaitForConnection, 0},
      {ScreenType::kStartDownload, 0},
      {ScreenType::kDownloadError, 2},
      {ScreenType::kNetworkError, 2},
      {ScreenType::kPasswordError, 2},
      {ScreenType::kConnectionError, 2}};

  ScreenType current_screen_{ScreenType::kWelcomeScreen};
  // Previous screen only used when changing the language so you know what
  // screen to return to after selection.
  ScreenType previous_screen_{ScreenType::kWelcomeScreen};

  // The `index_` shows which button is highlighted in the `current_screen_`,
  // uses menu_count of current screen to stay in bounds.
  int index_{1};

  // Determines whether we want to display the update engine state changes to
  // the UI. Only necessary after user has entered their password and connected
  // to the network.
  bool display_update_engine_state_{false};

  // Used to keep track of the last seen Update Engine stage to prevent
  // unnecessary screen changes.
  update_engine::Operation previous_update_state_{
      update_engine::Operation::IDLE};
};

}  // namespace screens

#endif  // MINIOS_SCREENS_H_
