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

#include "content/browser/permissions/embedded_permission_control_checker.h"

#include <optional>

#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/render_frame_host_test_support.h"
#include "content/public/test/test_renderer_host.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom.h"
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
#include "url/gurl.h"

using blink::mojom::EmbeddedPermissionControlClient;
using blink::mojom::PermissionDescriptor;
using blink::mojom::PermissionDescriptorPtr;
using blink::mojom::PermissionName;
using blink::mojom::PermissionService;
using blink::mojom::PermissionStatus;
using ::testing::_;

namespace content {

namespace {

constexpr static int kMaxPEPCPerPage = 2;

class MockEmbeddedPermissionControlClient
    : public EmbeddedPermissionControlClient {
 public:
  explicit MockEmbeddedPermissionControlClient(
      mojo::PendingReceiver<EmbeddedPermissionControlClient> pending_receiver) {
    receiver_.Bind(std::move(pending_receiver));
  }
  ~MockEmbeddedPermissionControlClient() override = default;

  MOCK_METHOD2(
      OnEmbeddedPermissionControlRegistered,
      void(bool allowed,
           const std::optional<std::vector<PermissionStatus>>& statuses));

  void ExpectEmbeddedPermissionControlRegistered() {
    base::RunLoop run_loop;
    EXPECT_CALL(*this, OnEmbeddedPermissionControlRegistered(/*allow*/ true, _))
        .Times(1);
    run_loop.RunUntilIdle();
  }

  void ExpectEmbeddedPermissionControlNotRegistered() {
    base::RunLoop run_loop;
    EXPECT_CALL(*this, OnEmbeddedPermissionControlRegistered(/*allow*/ true, _))
        .Times(0);
    run_loop.RunUntilIdle();
  }

 private:
  mojo::Receiver<EmbeddedPermissionControlClient> receiver_{this};
};

}  // namespace

class EmbeddedPermissionControlCheckerTest
    : public content::RenderViewHostTestHarness {
 public:
  EmbeddedPermissionControlCheckerTest()
      : scoped_feature_list_(features::kPermissionElement) {}
  EmbeddedPermissionControlCheckerTest(
      const EmbeddedPermissionControlCheckerTest&) = delete;
  EmbeddedPermissionControlCheckerTest& operator=(
      const EmbeddedPermissionControlCheckerTest&) = delete;
  ~EmbeddedPermissionControlCheckerTest() override = default;

  void SetUp() override {
    content::RenderViewHostTestHarness::SetUp();
    SetContents(CreateTestWebContents());
    NavigateAndCommit(GURL("https://www.google.com"));
    content::CreatePermissionService(
        main_rfh(), permission_service_.BindNewPipeAndPassReceiver());
  }

  PermissionService* permission_service() { return permission_service_.get(); }

  std::unique_ptr<MockEmbeddedPermissionControlClient>
  CreateEmbeddedPermissionControlClient(
      std::vector<PermissionName> permissions) {
    mojo::PendingRemote<EmbeddedPermissionControlClient> mojo_client;
    auto client = std::make_unique<MockEmbeddedPermissionControlClient>(
        mojo_client.InitWithNewPipeAndPassReceiver());

    std::vector<PermissionDescriptorPtr> permission_descriptors;
    permission_descriptors.reserve(permissions.size());
    base::ranges::transform(permissions,
                            std::back_inserter(permission_descriptors),
                            [](const auto& permission) {
                              auto descriptor = PermissionDescriptor::New();
                              descriptor->name = permission;
                              return descriptor;
                            });

    permission_service()->RegisterPageEmbeddedPermissionControl(
        std::move(permission_descriptors), std::move(mojo_client));
    return client;
  }

 private:
  mojo::Remote<PermissionService> permission_service_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_F(EmbeddedPermissionControlCheckerTest,
       RegisterPageEmbeddedPermissionSinglePermission) {
  for (PermissionName name :
       {PermissionName::AUDIO_CAPTURE, PermissionName::VIDEO_CAPTURE,
        PermissionName::GEOLOCATION}) {
    std::vector<std::unique_ptr<MockEmbeddedPermissionControlClient>> clients(
        kMaxPEPCPerPage);
    for (size_t i = 0; i < kMaxPEPCPerPage; ++i) {
      clients[i] = CreateEmbeddedPermissionControlClient({name});
      clients[i]->ExpectEmbeddedPermissionControlRegistered();
    }

    auto pending_client_1 = CreateEmbeddedPermissionControlClient({name});
    pending_client_1->ExpectEmbeddedPermissionControlNotRegistered();
    auto pending_client_2 = CreateEmbeddedPermissionControlClient({name});
    pending_client_2->ExpectEmbeddedPermissionControlNotRegistered();
    clients.pop_back();
    pending_client_1->ExpectEmbeddedPermissionControlRegistered();
    pending_client_2->ExpectEmbeddedPermissionControlNotRegistered();
    clients.pop_back();
    pending_client_2->ExpectEmbeddedPermissionControlRegistered();
  }
}

TEST_F(EmbeddedPermissionControlCheckerTest,
       RegisterPageEmbeddedPermissionMultiplePermissions) {
  std::vector<std::unique_ptr<MockEmbeddedPermissionControlClient>>
      grouped_clients(kMaxPEPCPerPage);
  for (size_t i = 0; i < kMaxPEPCPerPage; ++i) {
    grouped_clients[i] = CreateEmbeddedPermissionControlClient(
        {PermissionName::AUDIO_CAPTURE, PermissionName::VIDEO_CAPTURE});
    grouped_clients[i]->ExpectEmbeddedPermissionControlRegistered();
  }

  // Embedded permission control of a single permission will not count towards
  // the grouped one.
  for (PermissionName name :
       {PermissionName::AUDIO_CAPTURE, PermissionName::VIDEO_CAPTURE,
        PermissionName::GEOLOCATION}) {
    std::vector<std::unique_ptr<MockEmbeddedPermissionControlClient>> clients(
        kMaxPEPCPerPage);
    for (size_t i = 0; i < kMaxPEPCPerPage; ++i) {
      clients[i] = CreateEmbeddedPermissionControlClient({name});
      clients[i]->ExpectEmbeddedPermissionControlRegistered();
    }
  }

  // Changing order of permissions does not matter.
  auto pending_client_1 = CreateEmbeddedPermissionControlClient(
      {PermissionName::VIDEO_CAPTURE, PermissionName::AUDIO_CAPTURE});
  pending_client_1->ExpectEmbeddedPermissionControlNotRegistered();
  auto pending_client_2 = CreateEmbeddedPermissionControlClient(
      {PermissionName::VIDEO_CAPTURE, PermissionName::AUDIO_CAPTURE});
  pending_client_2->ExpectEmbeddedPermissionControlNotRegistered();
  grouped_clients.pop_back();
  pending_client_1->ExpectEmbeddedPermissionControlRegistered();
  pending_client_2->ExpectEmbeddedPermissionControlNotRegistered();
  grouped_clients.pop_back();
  pending_client_2->ExpectEmbeddedPermissionControlRegistered();
}

}  // namespace content
