// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>
#include <string_view>
#include <tuple>

#include "base/notreached.h"
#include "base/strings/to_string.h"
#include "chrome/browser/extensions/chrome_test_extension_loader.h"
#include "chrome/browser/extensions/extension_keybinding_registry.h"
#include "chrome/browser/extensions/install_verifier.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/supervised_user/supervised_user_test_util.h"
#include "chrome/browser/ui/extensions/extensions_dialogs.h"
#include "chrome/browser/ui/supervised_user/parent_permission_dialog.h"
#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
#include "chrome/test/interaction/interactive_browser_test.h"
#include "chrome/test/supervised_user/browser_user.h"
#include "chrome/test/supervised_user/family_live_test.h"
#include "components/prefs/pref_service.h"
#include "components/supervised_user/core/common/pref_names.h"
#include "components/supervised_user/test_support/family_link_settings_state_management.h"
#include "content/public/test/browser_test.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/test/test_extension_dir.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/interaction/element_identifier.h"

namespace supervised_user {
namespace {

static constexpr std::string_view kChromeManageExternsionsUrl =
    "chrome://extensions/";
static constexpr std::string_view kExtensionSiteSettingsUrl =
    "chrome://settings/content/siteDetails?site=chrome-extension://";
static constexpr std::string_view kExtensionName = "An Extension";

// TODO(b/321242366): Consider moving to helper class.
// Checks if a page title matches the given regexp in ecma script dialect.
InteractiveBrowserTestApi::StateChange PageWithMatchingTitle(
    std::string_view title_regexp) {
  DEFINE_LOCAL_CUSTOM_ELEMENT_EVENT_TYPE(kStateChange);
  InteractiveBrowserTestApi::StateChange state_change;
  state_change.type =
      InteractiveBrowserTestApi::StateChange::Type::kConditionTrue;
  state_change.event = kStateChange;
  state_change.test_function = base::StringPrintf(R"js(
    () => /%s/.test(document.title)
  )js",
                                                  title_regexp.data());
  state_change.continue_across_navigation = true;
  return state_change;
}

// Test the behavior of handling extensions for supervised users.
class SupervisedUserExtensionsParentalControlsUiTest
    : public InteractiveFamilyLiveTest,
      public testing::WithParamInterface<
          std::tuple<FamilyLiveTest::RpcMode,
                     /*permissions_switch_state=*/FamilyLinkToggleState,
                     /*extensions_switch_state=*/FamilyLinkToggleState>> {
 public:
  SupervisedUserExtensionsParentalControlsUiTest()
      : InteractiveFamilyLiveTest(GetRpcMode()) {}

 protected:
  // Child tries to enable a disabled extension (which is pending parent
  // approval) by clicking at the extension's toggle.
  // When the Extensions toggle is ON and used to manage the extensions,
  // the extension should be already enabled.
  // In that case the method only verifies the enabled state.
  auto ChildClicksEnableExtensionIfExtensionDisabled(
      ui::ElementIdentifier kChildTab,
      bool expected_extension_enabled) {
    return Steps(
        ExecuteJs(kChildTab, base::StringPrintf(
                                 R"js(
                () => {
                  const view_manager =
                    document.querySelector("extensions-manager").shadowRoot
                      .querySelector("#container").querySelector("#viewManager");
                  if (!view_manager) {
                    throw Error("Path to view_manager element is invalid.");
                  }
                  const container = view_manager.querySelector("#items-list")
                    .shadowRoot.querySelector("#container");
                  if (!container) {
                    throw Error("Path to container element is invalid.");
                  }
                  const count = container.querySelectorAll("extensions-item").length;
                  if (count !== 1) {
                    throw Error("Encountered unexpected number of extensions: " + count);
                  }
                  const extn = container.querySelectorAll("extensions-item")[0];
                  if (!extn) {
                    throw Error("Path to extension element is invalid.");
                  }
                  const toggle = extn.shadowRoot.querySelector("#enableToggle");
                  if (!toggle) {
                    throw Error("Path to extension toggle is invalid.");
                  }
                  if (toggle.ariaPressed != "%s") {
                    throw Error("Extension toggle in unexpected state: " + toggle.ariaPressed);
                  }
                  if (toggle.ariaPressed == "false") {
                    toggle.click();
                  }
                }
              )js",
                                 base::ToString(expected_extension_enabled))),
        Log("Child inspected extension toggle."));
  }

  // Installs programmatically (not through the UI) an extension for the given
  // user.
  void InstallExtension(Profile* profile) {
    std::string extension_manifest = base::StringPrintf(
        R"({
            "name": "%s",
            "manifest_version": 3,
            "version": "0.1",
            "host_permissions": ["<all_urls>"],
            "permissions": [ "geolocation" ]
          })",
        kExtensionName.data());
    extensions::TestExtensionDir extension_dir;
    extension_dir.WriteManifest(extension_manifest);

    extensions::ChromeTestExtensionLoader extension_loader(profile);
    extension_loader.set_ignore_manifest_warnings(true);
    extension_loader.LoadExtension(extension_dir.Pack());
  }

  ui::ElementIdentifier GetTargetUIElement() {
    CHECK(GetExtensionsSwitchTargetState() == FamilyLinkToggleState::kDisabled);
    // Parent approval dialog should appear.
    return ParentPermissionDialog::kDialogViewIdForTesting;
  }

  // Navigates to the `Settings` page for the installed extension under test
  // and inspects the permissions granted to the `Location` setting.
  // Checks if the `Locations` attribute is editable or not (html attribute
  // should be disabled), respecting the configuration of the "Permissions"
  // switch in Family Link.
  auto CheckExtensionLocationPermissions(ui::ElementIdentifier kChildElementId,
                                         Profile* profile) {
    extensions::ExtensionId installed_extension_id;
    const auto& installed_extensions =
        extensions::ExtensionRegistry::Get(profile)
            ->GenerateInstalledExtensionsSet();
    for (const auto& extension : installed_extensions) {
      if (extension->name() == kExtensionName) {
        installed_extension_id = extension->id();
        break;
      }
    }
    CHECK(installed_extension_id.size() > 0)
        << "There must be an installed extension.";

    // When the Permissions FL switch is Off, the Location permissions button
    // should be disabled (unmodifiable).
    bool permissions_button_greyed_out =
        GetPermissionsSwitchTargetState() == FamilyLinkToggleState::kDisabled;
    return Steps(
        Log("With installed extension : " + installed_extension_id),
        NavigateWebContents(kChildElementId,
                            GURL(std::string(kExtensionSiteSettingsUrl) +
                                 std::string(installed_extension_id))),
        WaitForStateChange(kChildElementId, PageWithMatchingTitle("Settings")),
        Log("With extension settings page open."),
        // Detect the Location permission and check whether it's user
        // modifiable.
        ExecuteJs(kChildElementId,
                  base::StringPrintf(
                      R"js(
          () => { const location_permission = document.querySelector("body > settings-ui")
                .shadowRoot.querySelector("#main")
                .shadowRoot.querySelector("settings-basic-page")
                .shadowRoot.querySelector("#basicPage > settings-section.expanded > settings-privacy-page")
                .shadowRoot.querySelector("#pages > settings-subpage > site-details")
                .shadowRoot.querySelector('[label="Location"]')
                .shadowRoot.querySelector("#permission");
                if (!location_permission) {
                  throw Error('No location permission menu was found.');
                }
                if (location_permission.disabled === "%s") {
                  throw Error('Unexpected Location Permission state: ' + permission_drop.disabled);
                }
              }
          )js",
                      base::ToString(permissions_button_greyed_out))),
        Log("Child inspected Location Permission button."));
  }

  auto CheckForParentDialogIfExtensionDisabled(
      bool is_expected_extension_enabled) {
    if (is_expected_extension_enabled) {
      // No dialog appears in this case.
      return Steps(Log("No dialog check is done, the extension is enabled."));
    }
    auto target_ui_element_id = GetTargetUIElement();
    return Steps(
        Log(base::StringPrintf("Waiting for the %s to appear.",
                               (target_ui_element_id ==
                                ParentPermissionDialog::kDialogViewIdForTesting)
                                   ? "parent approval dialog"
                                   : "blocked extension message")),
        WaitForShow(target_ui_element_id),
        Log(base::StringPrintf("The %s appears.",
                               (target_ui_element_id ==
                                ParentPermissionDialog::kDialogViewIdForTesting)
                                   ? "parent approval dialog"
                                   : "blocked extension message")));
  }

  static FamilyLiveTest::RpcMode GetRpcMode() {
    return std::get<0>(GetParam());
  }

  static FamilyLinkToggleState GetPermissionsSwitchTargetState() {
    return std::get<1>(GetParam());
  }

  static FamilyLinkToggleState GetExtensionsSwitchTargetState() {
    return std::get<2>(GetParam());
  }
};

IN_PROC_BROWSER_TEST_P(SupervisedUserExtensionsParentalControlsUiTest,
                       ChildTogglesExtensionMissingParentApproval) {
  extensions::ScopedInstallVerifierBypassForTest install_verifier_bypass;

  DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kChildElementId);
  DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(InIntendedStateObserver,
                                      kDefineStateObserverId);
  DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(InIntendedStateObserver,
                                      kResetStateObserverId);
  const int child_tab_index = 0;

  // The extensions should be disabled (pending parent approval) in all cases,
  // expect when the new "Extensions" FL switch is ON.
  const bool should_be_enabled =
      GetExtensionsSwitchTargetState() == FamilyLinkToggleState::kEnabled;

  TurnOnSync();

  // Set the FL switch in the value that require parent approvals for
  // extension installation.
  RunTestSequence(Log("Set config that requires parental approvals."),
                  WaitForStateSeeding(
                      kResetStateObserverId, child(),
                      FamilyLinkSettingsState::SetAdvancedSettingsDefault()));

  InstallExtension(&child().profile());

  RunTestSequence(InAnyContext(
      Log("Given an installed disabled extension."),
      // Parent sets both the FL Permissions and Extensions switches.
      // Only one of them impacts the handling of supervised user extensions.
      WaitForStateSeeding(
          kDefineStateObserverId, child(),
          FamilyLinkSettingsState::AdvancedSettingsToggles(
              {FamilyLinkToggleConfiguration(
                   {.type = FamilyLinkToggleType::kExtensionsToggle,
                    .state = GetExtensionsSwitchTargetState()}),
               FamilyLinkToggleConfiguration(
                   {.type = FamilyLinkToggleType::kPermissionsToggle,
                    .state = GetPermissionsSwitchTargetState()})})),
      // Child navigates to the extensions page and tries to enable the
      // extension, if it is disabled.
      Log("When child visits the extensions management page."),
      InstrumentTab(kChildElementId, child_tab_index, &child().browser()),
      NavigateWebContents(kChildElementId, GURL(kChromeManageExternsionsUrl)),
      WaitForStateChange(kChildElementId, PageWithMatchingTitle("Extensions")),
      Log("When child tries to enable the extension."),
      ChildClicksEnableExtensionIfExtensionDisabled(kChildElementId,
                                                    should_be_enabled),
      // If the extension is not already enabled, check that the expect UI
      // dialog appears.
      CheckForParentDialogIfExtensionDisabled(should_be_enabled),
      CheckExtensionLocationPermissions(kChildElementId, &child().profile())));
}

INSTANTIATE_TEST_SUITE_P(
    All,
    SupervisedUserExtensionsParentalControlsUiTest,
    testing::Combine(
        testing::Values(FamilyLiveTest::RpcMode::kProd,
                        FamilyLiveTest::RpcMode::kTestImpersonation),
        /*permissions_switch_target_value=*/
        testing::Values(FamilyLinkToggleState::kEnabled,
                        FamilyLinkToggleState::kDisabled),
        /*extensions_switch_target_value==*/
        testing::Values(FamilyLinkToggleState::kEnabled,
                        FamilyLinkToggleState::kDisabled)),
    [](const auto& info) {
      return ToString(std::get<0>(info.param)) +
             std::string(
                 (std::get<1>(info.param) == FamilyLinkToggleState::kEnabled
                      ? "WithPermissionsOn"
                      : "WithPermissionsOff")) +
             std::string(
                 (std::get<2>(info.param) == FamilyLinkToggleState::kEnabled
                      ? "WithExtensionsOn"
                      : "WithExtensionsOff"));
    });

}  // namespace
}  // namespace supervised_user
