// Copyright 2018 The Chromium 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 "ash/public/cpp/ash_switches.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/optional.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api.h"
#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
#include "chrome/browser/chromeos/login/screens/gaia_view.h"
#include "chrome/browser/chromeos/login/screens/sync_consent_screen.h"
#include "chrome/browser/chromeos/login/screens/update_screen.h"
#include "chrome/browser/chromeos/login/test/js_checker.h"
#include "chrome/browser/chromeos/login/test/oobe_base_test.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/ui/ash/tablet_mode_client.h"
#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/update_engine_client.h"
#include "content/public/browser/notification_service.h"

namespace chromeos {
namespace {
constexpr base::TimeDelta kJsConditionCheckFrequency =
    base::TimeDelta::FromMilliseconds(200);
constexpr base::TimeDelta kLoginDisplayHostCheckFrequency =
    base::TimeDelta::FromMilliseconds(200);

// Waits for js condition to be fulfilled.
class JsConditionWaiter {
 public:
  enum class Options {
    kNone,
    kSatisifyIfOobeDestroyed,
  };

  // If |options| is true, we are waiting for the end condition, so it is
  // automatically fullfilled if LoginDisplayHost is already destroyed.
  JsConditionWaiter(const test::JSChecker& js_checker,
                    const std::string& js_condition,
                    Options options)
      : js_checker_(js_checker),
        js_condition_(js_condition),
        options_(options) {}

  ~JsConditionWaiter() = default;

  void Wait() {
    if (IsConditionFulfilled())
      return;

    timer_.Start(FROM_HERE, kJsConditionCheckFrequency, this,
                 &JsConditionWaiter::CheckCondition);
    run_loop_.Run();
  }

 private:
  bool IsConditionFulfilled() {
    return (options_ == Options::kSatisifyIfOobeDestroyed &&
            !LoginDisplayHost::default_host()) ||
           js_checker_.GetBool(js_condition_);
  }

  void CheckCondition() {
    if (IsConditionFulfilled()) {
      run_loop_.Quit();
      timer_.Stop();
    }
  }

  test::JSChecker js_checker_;
  const std::string js_condition_;
  const Options options_;

  base::RepeatingTimer timer_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(JsConditionWaiter);
};

// Waits for LoginDisplayHost to shut down.
class LoginDisplayHostShutdownWaiter {
 public:
  LoginDisplayHostShutdownWaiter() = default;
  ~LoginDisplayHostShutdownWaiter() = default;

  void Wait() {
    if (!LoginDisplayHost::default_host())
      return;

    timer_.Start(FROM_HERE, kLoginDisplayHostCheckFrequency, this,
                 &LoginDisplayHostShutdownWaiter::CheckCondition);
    run_loop_.Run();
  }

 private:
  void CheckCondition() {
    if (!LoginDisplayHost::default_host()) {
      run_loop_.Quit();
      timer_.Stop();
    }
  }

  base::RepeatingTimer timer_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(LoginDisplayHostShutdownWaiter);
};

class ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver {
 public:
  explicit ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver(
      extensions::QuickUnlockPrivateGetAuthTokenFunction::TestObserver*
          observer) {
    extensions::QuickUnlockPrivateGetAuthTokenFunction::SetTestObserver(
        observer);
  }
  ~ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver() {
    extensions::QuickUnlockPrivateGetAuthTokenFunction::SetTestObserver(
        nullptr);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(
      ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver);
};

}  // namespace

class OobeInteractiveUITest
    : public OobeBaseTest,
      public extensions::QuickUnlockPrivateGetAuthTokenFunction::TestObserver,
      public ::testing::WithParamInterface<std::tuple<bool, bool>> {
 public:
  struct Parameters {
    bool is_tablet;
    bool is_quick_unlock_enabled;

    std::string ToString() const {
      return std::string("{is_tablet: ") + (is_tablet ? "true" : "false") +
             ", is_quick_unlock_enabled: " +
             (is_quick_unlock_enabled ? "true" : "false") + "}";
    }
  };

  OobeInteractiveUITest() = default;
  ~OobeInteractiveUITest() override = default;

  void SetUp() override {
    params_ = Parameters();
    std::tie(params_->is_tablet, params_->is_quick_unlock_enabled) = GetParam();
    LOG(INFO) << "OobeInteractiveUITest() started with params "
              << params_->ToString();
    OobeBaseTest::SetUp();
  }

  void TearDown() override {
    OobeBaseTest::TearDown();
    params_.reset();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    OobeBaseTest::SetUpCommandLine(command_line);

    if (params_->is_tablet)
      command_line->AppendSwitch(ash::switches::kAshEnableTabletMode);
  }

  void SetUpInProcessBrowserTestFixture() override {
    OobeBaseTest::SetUpInProcessBrowserTestFixture();

    if (params_->is_quick_unlock_enabled)
      quick_unlock::EnableForTesting();
  }

  void TearDownOnMainThread() override {
    // If the login display is still showing, exit gracefully.
    if (LoginDisplayHost::default_host()) {
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&chrome::AttemptExit));
      RunUntilBrowserProcessQuits();
    }

    OobeBaseTest::TearDownOnMainThread();
  }

  // QuickUnlockPrivateGetAuthTokenFunction::TestObserver:
  void OnGetAuthTokenCalled(const std::string& password) override {
    quick_unlock_private_get_auth_token_password_ = password;
  }

  void WaitForLoginDisplayHostShutdown() {
    if (!LoginDisplayHost::default_host())
      return;

    LOG(INFO)
        << "OobeInteractiveUITest: Waiting for LoginDisplayHost to shut down.";
    LoginDisplayHostShutdownWaiter().Wait();
    LOG(INFO) << "OobeInteractiveUITest: LoginDisplayHost is down.";
  }

  void WaitForOobeWelcomeScreen() {
    content::WindowedNotificationObserver observer(
        chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
        content::NotificationService::AllSources());
    observer.Wait();

    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'connect'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
  }

  void RunWelcomeScreenChecks() {
#if defined(GOOGLE_CHROME_BUILD)
    constexpr int kNumberOfVideosPlaying = 1;
#else
    constexpr int kNumberOfVideosPlaying = 0;
#endif

    js_checker_.ExpectTrue("!$('oobe-welcome-md').$.welcomeScreen.hidden");
    js_checker_.ExpectTrue("$('oobe-welcome-md').$.accessibilityScreen.hidden");
    js_checker_.ExpectTrue("$('oobe-welcome-md').$.languageScreen.hidden");
    js_checker_.ExpectTrue("$('oobe-welcome-md').$.timezoneScreen.hidden");

    js_checker_.ExpectEQ(
        "(() => {let cnt = 0; for (let v of "
        "$('oobe-welcome-md').$.welcomeScreen.root.querySelectorAll('video')) "
        "{  cnt += v.paused ? 0 : 1; }; return cnt; })()",
        kNumberOfVideosPlaying);
  }

  void TapWelcomeNext() {
    js_checker_.ExecuteAsync(
        "$('oobe-welcome-md').$.welcomeScreen.$.welcomeNextButton.click()");
  }

  void WaitForNetworkSelectionScreen() {
    JsConditionWaiter(
        js_checker_,
        "Oobe.getInstance().currentScreen.id == 'network-selection'",
        JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO)
        << "OobeInteractiveUITest: Switched to 'network-selection' screen.";
  }

  void RunNetworkSelectionScreenChecks() {
    js_checker_.ExpectTrue(
        "!$('oobe-network-md').$.networkDialog.querySelector('oobe-next-button'"
        ").disabled");
  }

  void TapNetworkSelectionNext() {
    js_checker_.ExecuteAsync(
        "$('oobe-network-md').$.networkDialog.querySelector('oobe-next-button')"
        ".click()");
  }

  void WaitForEulaScreen() {
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'eula'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Switched to 'eula' screen.";
  }

  void RunEulaScreenChecks() {
    // Wait for actual EULA to appear.
    JsConditionWaiter(js_checker_, "!$('oobe-eula-md').$.eulaDialog.hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    js_checker_.ExpectTrue("!$('oobe-eula-md').$.acceptButton.disabled");
  }

  void TapEulaAccept() {
    js_checker_.ExecuteAsync("$('oobe-eula-md').$.acceptButton.click();");
  }

  void WaitForUpdateScreen() {
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'update'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    JsConditionWaiter(js_checker_, "!$('update').hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();

    LOG(INFO) << "OobeInteractiveUITest: Switched to 'update' screen.";
  }

  void ExitUpdateScreenNoUpdate() {
    UpdateScreen* screen = static_cast<UpdateScreen*>(
        WizardController::default_controller()->GetScreen(
            OobeScreen::SCREEN_OOBE_UPDATE));
    UpdateEngineClient::Status status;
    status.status = UpdateEngineClient::UPDATE_STATUS_ERROR;
    screen->UpdateStatusChanged(status);
  }

  void WaitForGaiaSignInScreen() {
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'gaia-signin'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Switched to 'gaia-signin' screen.";
  }

  void LogInAsRegularUser() {
    LoginDisplayHost::default_host()
        ->GetOobeUI()
        ->GetGaiaScreenView()
        ->ShowSigninScreenForTest(OobeBaseTest::kFakeUserEmail,
                                  OobeBaseTest::kFakeUserPassword,
                                  OobeBaseTest::kEmptyUserServices);
    LOG(INFO) << "OobeInteractiveUITest: Logged in.";
  }

  void WaitForSyncConsentScreen() {
    LOG(INFO) << "OobeInteractiveUITest: Waiting for 'sync-consent' screen.";
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'sync-consent'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
  }

  void ExitScreenSyncConsent() {
    SyncConsentScreen* screen = static_cast<SyncConsentScreen*>(
        WizardController::default_controller()->GetScreen(
            OobeScreen::SCREEN_SYNC_CONSENT));

    screen->SetProfileSyncDisabledByPolicyForTesting(true);
    screen->OnStateChanged(nullptr);
    LOG(INFO) << "OobeInteractiveUITest: Waiting for 'sync-consent' screen "
                 "to close.";
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id != 'sync-consent'",
                      JsConditionWaiter::Options::kSatisifyIfOobeDestroyed)
        .Wait();
  }

  void WaitForFingerprintScreen() {
    LOG(INFO)
        << "OobeInteractiveUITest: Waiting for 'fingerprint-setup' screen.";
    JsConditionWaiter(
        js_checker_,
        "Oobe.getInstance().currentScreen.id == 'fingerprint-setup'",
        JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen "
                 "to show.";
    JsConditionWaiter(js_checker_, "!$('fingerprint-setup').hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen "
                 "to initializes.";
    JsConditionWaiter(js_checker_, "!$('fingerprint-setup-impl').hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen "
                 "to show setupFingerprint.";
    JsConditionWaiter(js_checker_,
                      "!$('fingerprint-setup-impl').$.setupFingerprint.hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();
  }

  void RunFingerprintScreenChecks() {
    js_checker_.ExpectTrue("!$('fingerprint-setup').hidden");
    js_checker_.ExpectTrue("!$('fingerprint-setup-impl').hidden");
    js_checker_.ExpectTrue(
        "!$('fingerprint-setup-impl').$.setupFingerprint.hidden");
    js_checker_.ExecuteAsync(
        "$('fingerprint-setup-impl').$.showSensorLocationButton.click()");
    js_checker_.ExpectTrue(
        "$('fingerprint-setup-impl').$.setupFingerprint.hidden");
    LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup "
                 "to switch to placeFinger.";
    JsConditionWaiter(js_checker_,
                      "!$('fingerprint-setup-impl').$.placeFinger.hidden",
                      JsConditionWaiter::Options::kNone)
        .Wait();
  }

  void ExitFingerprintPinSetupScreen() {
    js_checker_.ExpectTrue("!$('fingerprint-setup-impl').$.placeFinger.hidden");
    // This might be the last step in flow. Synchronious execute gets stuck as
    // WebContents may be destroyed in the process. So it may never return.
    // So we use ExecuteAsync() here.
    js_checker_.ExecuteAsync(
        "$('fingerprint-setup-impl').$.setupFingerprintLater.click()");
    LOG(INFO) << "OobeInteractiveUITest: Waiting for fingerprint setup screen "
                 "to close.";
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id !="
                      "'fingerprint-setup'",
                      JsConditionWaiter::Options::kSatisifyIfOobeDestroyed)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: 'fingerprint-setup' screen done.";
  }

  void WaitForDiscoverScreen() {
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'discover'",
                      JsConditionWaiter::Options::kNone)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: Switched to 'discover' screen.";
  }

  void RunDiscoverScreenChecks() {
    js_checker_.ExpectTrue("!$('discover').hidden");
    js_checker_.ExpectTrue("!$('discover-impl').hidden");
    js_checker_.ExpectTrue(
        "!$('discover-impl').root.querySelector('discover-pin-setup-module')."
        "hidden");
    js_checker_.ExpectTrue(
        "!$('discover-impl').root.querySelector('discover-pin-setup-module').$."
        "setup.hidden");
    EXPECT_TRUE(quick_unlock_private_get_auth_token_password_.has_value());
    EXPECT_EQ(quick_unlock_private_get_auth_token_password_,
              OobeBaseTest::kFakeUserPassword);
  }

  void ExitDiscoverPinSetupScreen() {
    // This might be the last step in flow. Synchronious execute gets stuck as
    // WebContents may be destroyed in the process. So it may never return.
    // So we use ExecuteAsync() here.
    js_checker_.ExecuteAsync(
        "$('discover-impl').root.querySelector('discover-pin-setup-module')."
        "$.setupSkipButton.click()");
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id != 'discover'",
                      JsConditionWaiter::Options::kSatisifyIfOobeDestroyed)
        .Wait();
    LOG(INFO) << "OobeInteractiveUITest: 'discover' screen done.";
  }

  void WaitForUserImageScreen() {
    JsConditionWaiter(js_checker_,
                      "Oobe.getInstance().currentScreen.id == 'user-image'",
                      JsConditionWaiter::Options::kNone)
        .Wait();

    LOG(INFO) << "OobeInteractiveUITest: Switched to 'user-image' screen.";
  }

  void SimpleEndToEnd();

  base::Optional<std::string> quick_unlock_private_get_auth_token_password_;
  base::Optional<Parameters> params_;

 private:
  DISALLOW_COPY_AND_ASSIGN(OobeInteractiveUITest);
};

void OobeInteractiveUITest::SimpleEndToEnd() {
  ASSERT_TRUE(params_.has_value());
  ScopedQuickUnlockPrivateGetAuthTokenFunctionObserver scoped_observer(this);

  WaitForOobeWelcomeScreen();
  RunWelcomeScreenChecks();
  TapWelcomeNext();

  WaitForNetworkSelectionScreen();
  RunNetworkSelectionScreenChecks();
  TapNetworkSelectionNext();

#if defined(GOOGLE_CHROME_BUILD)
  WaitForEulaScreen();
  RunEulaScreenChecks();
  TapEulaAccept();
#endif

  WaitForUpdateScreen();
  ExitUpdateScreenNoUpdate();
  WaitForGaiaSignInScreen();

  LogInAsRegularUser();

#if defined(GOOGLE_CHROME_BUILD)
  WaitForSyncConsentScreen();
  ExitScreenSyncConsent();
#endif

  if (quick_unlock::IsEnabledForTesting()) {
    WaitForFingerprintScreen();
    RunFingerprintScreenChecks();
    ExitFingerprintPinSetupScreen();
  }

  if (TabletModeClient::Get()->tablet_mode_enabled()) {
    WaitForDiscoverScreen();
    RunDiscoverScreenChecks();
    ExitDiscoverPinSetupScreen();
  }

  WaitForLoginDisplayHostShutdown();
}

IN_PROC_BROWSER_TEST_P(OobeInteractiveUITest, SimpleEndToEnd) {
  SimpleEndToEnd();
}

INSTANTIATE_TEST_CASE_P(OobeInteractiveUITestImpl,
                        OobeInteractiveUITest,
                        testing::Combine(testing::Bool(), testing::Bool()));

}  //  namespace chromeos
