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

#include <stddef.h>

#include <memory>
#include <utility>

#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/permissions_test_util.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/browser/extensions/test_extension_environment.h"
#include "chrome/common/extensions/permissions/chrome_permission_message_provider.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/testing_profile.h"
#include "components/crx_file/id_util.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/manifest.h"
#include "extensions/common/manifest_handlers/permissions_parser.h"
#include "extensions/common/permissions/permission_set.h"
#include "extensions/common/permissions/permissions_data.h"
#include "extensions/common/permissions/permissions_info.h"
#include "extensions/common/permissions/usb_device_permission.h"
#include "extensions/common/permissions/usb_device_permission_data.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"

using extensions::mojom::APIPermissionID;

namespace extensions {

// Tests that ChromePermissionMessageProvider provides not only correct, but
// meaningful permission messages that coalesce correctly where appropriate.
// There are 3 types of permission messages that need to be tested:
//  1. The combined list of active permissions, displayed at install time (or
//     when the app has been disabled automatically and needs to be re-enabled)
//  2. The split list of active permissions, displayed in the App Info dialog,
//     where the optional permissions are individually revokable
//  3. The list of requested optional permissions, displayed in a prompt to the
//     user when the app requests these during runtime
// Some of these tests are prefixed AntiTest_, since they demonstrate existing
// problematic functionality. These tests are prefixed with AntiTest_ and will
// be changed as the correct behaviour is implemented. TODOs in the test explain
// the currently problematic behaviour.
class PermissionMessagesUnittest : public testing::Test {
 public:
  PermissionMessagesUnittest()
      : message_provider_(new ChromePermissionMessageProvider()) {}

  PermissionMessagesUnittest(const PermissionMessagesUnittest&) = delete;
  PermissionMessagesUnittest& operator=(const PermissionMessagesUnittest&) =
      delete;

  ~PermissionMessagesUnittest() override {}

 protected:
  void CreateAndInstallExtensionWithPermissions(
      base::Value::List required_permissions,
      base::Value::List optional_permissions) {
    app_ = ExtensionBuilder("Test")
               .SetManifestKey("permissions", std::move(required_permissions))
               .SetManifestKey("optional_permissions",
                               std::move(optional_permissions))
               .SetID(crx_file::id_util::GenerateId("extension"))
               .SetLocation(mojom::ManifestLocation::kInternal)
               .Build();
    env_.GetExtensionService()->AddExtension(app_.get());
  }

  // Returns the permission messages that would display in the prompt that
  // requests all the optional permissions for the current |app_|.
  std::vector<std::u16string> GetOptionalPermissionMessages() {
    std::unique_ptr<const PermissionSet> granted_permissions =
        env_.GetExtensionPrefs()->GetGrantedPermissions(app_->id());
    const PermissionSet& optional_permissions =
        PermissionsParser::GetOptionalPermissions(app_.get());
    std::unique_ptr<const PermissionSet> requested_permissions =
        PermissionSet::CreateDifference(optional_permissions,
                                        *granted_permissions);
    return GetMessages(*requested_permissions);
  }

  void GrantOptionalPermissions() {
    permissions_test_util::GrantOptionalPermissionsAndWaitForCompletion(
        env_.profile(), *app_,
        PermissionsParser::GetOptionalPermissions(app_.get()));
  }

  std::vector<std::u16string> active_permissions() {
    return GetMessages(app_->permissions_data()->active_permissions());
  }

  std::vector<std::u16string> required_permissions() {
    return GetMessages(PermissionsParser::GetRequiredPermissions(app_.get()));
  }

  std::vector<std::u16string> optional_permissions() {
    return GetMessages(PermissionsParser::GetOptionalPermissions(app_.get()));
  }

 private:
  std::vector<std::u16string> GetMessages(const PermissionSet& permissions) {
    std::vector<std::u16string> messages;
    for (const PermissionMessage& msg :
         message_provider_->GetPermissionMessages(
             message_provider_->GetAllPermissionIDs(permissions,
                                                    app_->GetType()))) {
      messages.push_back(msg.message());
    }
    return messages;
  }

  extensions::TestExtensionEnvironment env_;
  std::unique_ptr<ChromePermissionMessageProvider> message_provider_;
  scoped_refptr<const Extension> app_;
};

// If an app has both the 'history' and 'tabs' permission, one should hide the
// other (the 'history' permission has superset permissions).
TEST_F(PermissionMessagesUnittest, HistoryHidesTabsMessage) {
  CreateAndInstallExtensionWithPermissions(
      base::Value::List().Append("tabs").Append("history"),
      base::Value::List());

  ASSERT_EQ(1U, required_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            required_permissions()[0]);

  ASSERT_EQ(0U, optional_permissions().size());
}

// If an app requests the 'history' permission, but already has the 'tabs'
// permission, only the new coalesced message is displayed.
TEST_F(PermissionMessagesUnittest, MixedPermissionMessagesCoalesceOnceGranted) {
  CreateAndInstallExtensionWithPermissions(
      base::Value::List().Append("tabs"),
      base::Value::List().Append("history"));

  ASSERT_EQ(1U, required_permissions().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      required_permissions()[0]);

  ASSERT_EQ(1U, optional_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            optional_permissions()[0]);

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      active_permissions()[0]);

  ASSERT_EQ(1U, GetOptionalPermissionMessages().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            GetOptionalPermissionMessages()[0]);

  GrantOptionalPermissions();

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            active_permissions()[0]);
}

// AntiTest: This behavior should be changed and improved.
// If an app requests the 'tabs' permission but already has the 'history'
// permission, a prompt is displayed. However, no prompt should appear at all,
// since 'tabs' is a subset of 'history' and the final list of permissions are
// not affected by this grant.
TEST_F(PermissionMessagesUnittest,
       AntiTest_PromptCanRequestSubsetOfAlreadyGrantedPermissions) {
  CreateAndInstallExtensionWithPermissions(
      base::Value::List().Append("history"),
      base::Value::List().Append("tabs"));

  ASSERT_EQ(1U, required_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            required_permissions()[0]);

  ASSERT_EQ(1U, optional_permissions().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      optional_permissions()[0]);

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            active_permissions()[0]);

  // TODO(sashab): This prompt should display no permissions, since READ is a
  // subset permission of WRITE.
  ASSERT_EQ(1U, GetOptionalPermissionMessages().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      GetOptionalPermissionMessages()[0]);

  GrantOptionalPermissions();

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_WRITE_ON_ALL_DEVICES),
            active_permissions()[0]);
}

// AntiTest: This behavior should be changed and improved.
// If an app requests the 'sessions' permission, nothing is displayed in the
// permission request prompt. However, the required permissions for the app are
// actually modified, so the prompt *should* display a message to prevent this
// permission from being granted for free.
TEST_F(PermissionMessagesUnittest,
       AntiTest_PromptCanBeEmptyButCausesChangeInPermissions) {
  CreateAndInstallExtensionWithPermissions(
      base::Value::List().Append("tabs"),
      base::Value::List().Append("sessions"));

  ASSERT_EQ(1U, required_permissions().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      required_permissions()[0]);

  ASSERT_EQ(0U, optional_permissions().size());

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(
      l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ),
      active_permissions()[0]);

  // TODO(sashab): This prompt should display the sessions permission message,
  // as well as warn the user that it can affect the existing 'tab' permission.
  ASSERT_EQ(0U, GetOptionalPermissionMessages().size());

  GrantOptionalPermissions();

  ASSERT_EQ(1U, active_permissions().size());
  EXPECT_EQ(l10n_util::GetStringUTF16(
                IDS_EXTENSION_PROMPT_WARNING_HISTORY_READ_ON_ALL_DEVICES),
            active_permissions()[0]);
}

class USBDevicePermissionMessagesTest : public testing::Test {
 public:
  USBDevicePermissionMessagesTest()
      : message_provider_(new ChromePermissionMessageProvider()) {}
  ~USBDevicePermissionMessagesTest() override {}

  PermissionMessages GetMessages(const PermissionIDSet& permissions) {
    return message_provider_->GetPermissionMessages(permissions);
  }

 private:
  std::unique_ptr<ChromePermissionMessageProvider> message_provider_;
};

TEST_F(USBDevicePermissionMessagesTest, SingleDevice) {
  {
    const char16_t kMessage[] =
        u"Access any PVR Mass Storage from HUMAX Co., Ltd. via USB";

    auto permission_list =
        base::Value::List().Append(base::Value::FromUniquePtrValue(
            UsbDevicePermissionData(0x02ad, 0x138c, -1, -1).ToValue()));
    base::Value permission_value = base::Value(std::move(permission_list));

    UsbDevicePermission permission(
        PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice));
    ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr));

    PermissionMessages messages = GetMessages(permission.GetPermissions());
    ASSERT_EQ(1U, messages.size());
    EXPECT_EQ(kMessage, messages.front().message());
  }
  {
    const char16_t kMessage[] = u"Access USB devices from HUMAX Co., Ltd.";

    base::Value::List permission_list;
    permission_list.Append(base::Value::FromUniquePtrValue(
        UsbDevicePermissionData(0x02ad, 0x138d, -1, -1).ToValue()));
    base::Value permission_value = base::Value(std::move(permission_list));

    UsbDevicePermission permission(
        PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice));
    ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr));

    PermissionMessages messages = GetMessages(permission.GetPermissions());
    ASSERT_EQ(1U, messages.size());
    EXPECT_EQ(kMessage, messages.front().message());
  }
  {
    const char16_t kMessage[] = u"Access USB devices from an unknown vendor";

    base::Value::List permission_list;
    permission_list.Append(base::Value::FromUniquePtrValue(
        UsbDevicePermissionData(0x02ae, 0x138d, -1, -1).ToValue()));
    base::Value permission_value = base::Value(std::move(permission_list));

    UsbDevicePermission permission(
        PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice));
    ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr));

    PermissionMessages messages = GetMessages(permission.GetPermissions());
    ASSERT_EQ(1U, messages.size());
    EXPECT_EQ(kMessage, messages.front().message());
  }
}

TEST_F(USBDevicePermissionMessagesTest, MultipleDevice) {
  const char16_t kMessage[] = u"Access any of these USB devices";
  const char* kDetails[] = {
      "PVR Mass Storage from HUMAX Co., Ltd.",
      "unknown devices from HUMAX Co., Ltd.",
      "devices from an unknown vendor"
  };

  // Prepare data set
  base::Value::List permission_list;
  permission_list.Append(base::Value::FromUniquePtrValue(
      UsbDevicePermissionData(0x02ad, 0x138c, -1, -1).ToValue()));
  // This device's product ID is not in Chrome's database.
  permission_list.Append(base::Value::FromUniquePtrValue(
      UsbDevicePermissionData(0x02ad, 0x138d, -1, -1).ToValue()));
  // This additional unknown product will be collapsed into the entry above.
  permission_list.Append(base::Value::FromUniquePtrValue(
      UsbDevicePermissionData(0x02ad, 0x138e, -1, -1).ToValue()));
  // This device's vendor ID is not in Chrome's database.
  permission_list.Append(base::Value::FromUniquePtrValue(
      UsbDevicePermissionData(0x02ae, 0x138d, -1, -1).ToValue()));
  // This additional unknown vendor will be collapsed into the entry above.
  permission_list.Append(base::Value::FromUniquePtrValue(
      UsbDevicePermissionData(0x02af, 0x138d, -1, -1).ToValue()));

  base::Value permission_value = base::Value(std::move(permission_list));

  UsbDevicePermission permission(
      PermissionsInfo::GetInstance()->GetByID(APIPermissionID::kUsbDevice));
  ASSERT_TRUE(permission.FromValue(&permission_value, nullptr, nullptr));

  PermissionMessages messages = GetMessages(permission.GetPermissions());
  ASSERT_EQ(1U, messages.size());
  EXPECT_EQ(kMessage, messages.front().message());
  const std::vector<std::u16string>& submessages =
      messages.front().submessages();
  ASSERT_EQ(std::size(kDetails), submessages.size());
  for (size_t i = 0; i < submessages.size(); i++)
    EXPECT_EQ(base::ASCIIToUTF16(kDetails[i]), submessages[i]);
}

}  // namespace extensions
