// Copyright 2022 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/permission_service_context.h"

#include <memory>

#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "content/browser/permissions/permission_controller_impl.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/weak_document_ptr.h"
#include "content/public/test/navigation_simulator.h"
#include "content/public/test/test_renderer_host.h"
#include "content/test/test_render_frame_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/permissions/permission_utils.h"
#include "third_party/blink/public/mojom/permissions/permission.mojom.h"
#include "url/origin.h"

namespace content {

namespace {
constexpr char kTestUrl[] = "https://google.com";
}

class TestPermissionObserver : public blink::mojom::PermissionObserver {
 public:
  TestPermissionObserver() = default;

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

  ~TestPermissionObserver() override = default;

  // Closes the bindings associated with this observer.
  void Close() { receiver_.reset(); }

  // Returns a pipe to this observer.
  mojo::PendingRemote<blink::mojom::PermissionObserver> GetRemote() {
    mojo::PendingRemote<blink::mojom::PermissionObserver> remote;
    receiver_.Bind(remote.InitWithNewPipeAndPassReceiver());
    return remote;
  }

  // Returns the number of events received by this observer.
  size_t change_event_count() const { return change_event_count_; }

  // blink::mojom::PermissionObserver implementation.
  void OnPermissionStatusChange(
      blink::mojom::PermissionStatus status) override {
    change_event_count_++;
  }

 private:
  size_t change_event_count_ = 0;
  mojo::Receiver<blink::mojom::PermissionObserver> receiver_{this};
};

class PermissionServiceContextTest : public RenderViewHostTestHarness {
 public:
  PermissionServiceContextTest() = default;
  PermissionServiceContextTest(const PermissionServiceContextTest&) = delete;
  PermissionServiceContextTest& operator=(const PermissionServiceContextTest&) =
      delete;
  ~PermissionServiceContextTest() override = default;

  void SetUp() override {
    RenderViewHostTestHarness::SetUp();
    origin_ = url::Origin::Create(GURL(kTestUrl));
    NavigateAndCommit(origin_.GetURL());
    permission_controller_ =
        PermissionControllerImpl::FromBrowserContext(browser_context());
    auto* render_frame_host = main_rfh();
    render_frame_host_impl_ =
        static_cast<RenderFrameHostImpl*>(render_frame_host);
    permission_service_context_ =
        PermissionServiceContext::GetOrCreateForCurrentDocument(
            render_frame_host);
  }

  void TearDown() override {
    permission_controller_ = nullptr;
    render_frame_host_impl_ = nullptr;
    permission_service_context_ = nullptr;
    RenderViewHostTestHarness::TearDown();
  }

  std::unique_ptr<TestPermissionObserver> CreateSubscription(
      PermissionType type,
      blink::mojom::PermissionStatus last_status,
      blink::mojom::PermissionStatus current_status) {
    permission_controller()->SetOverrideForDevTools(origin_, type, last_status);
    auto observer = std::make_unique<TestPermissionObserver>();
    permission_service_context()->CreateSubscription(
        type, origin_, current_status, last_status, observer->GetRemote());
    WaitForAsyncTasksToComplete();
    return observer;
  }

  void SimulatePermissionChangedEvent(PermissionType type,
                                      blink::mojom::PermissionStatus status) {
    permission_controller()->SetOverrideForDevTools(origin_, type, status);
    WaitForAsyncTasksToComplete();
  }

  // Waits until the Mojo task (async) has finished.
  void WaitForAsyncTasksToComplete() { task_environment()->RunUntilIdle(); }

  PermissionControllerImpl* permission_controller() {
    return permission_controller_;
  }

  PermissionServiceContext* permission_service_context() {
    return permission_service_context_;
  }

  RenderFrameHostImpl* render_frame_host() { return render_frame_host_impl_; }

 private:
  url::Origin origin_;
  raw_ptr<PermissionControllerImpl> permission_controller_;
  raw_ptr<RenderFrameHostImpl> render_frame_host_impl_;
  raw_ptr<PermissionServiceContext> permission_service_context_;
};

TEST_F(PermissionServiceContextTest, DispatchPermissionChangeEvent) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);
  EXPECT_EQ(observer->change_event_count(), 1U);
}

TEST_F(PermissionServiceContextTest,
       DispatchPermissionChangeEventInBackForwardCache) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);

  // After dispatching changed events when the render frame host is active,
  // the event counter should increment as expected.
  EXPECT_EQ(observer->change_event_count(), 1U);

  // Same origin child sub-frame should also receive changed events but should
  // not double increment the parent's counter.
  RenderFrameHost* child =
      RenderFrameHostTester::For(render_frame_host())->AppendChild("");
  RenderFrameHostTester::For(child)->InitializeRenderFrameIfNeeded();
  auto navigation_simulator =
      content::NavigationSimulator::CreateRendererInitiated(GURL(kTestUrl),
                                                            child);
  navigation_simulator->Commit();
  child = navigation_simulator->GetFinalRenderFrameHost();
  auto* permission_service_context =
      PermissionServiceContext::GetOrCreateForCurrentDocument(child);
  auto observer_child = std::make_unique<TestPermissionObserver>();
  permission_service_context->CreateSubscription(
      PermissionType::GEOLOCATION, url::Origin::Create(GURL(kTestUrl)),
      blink::mojom::PermissionStatus::ASK, blink::mojom::PermissionStatus::ASK,
      observer_child->GetRemote());
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 2U);
  EXPECT_EQ(observer_child->change_event_count(), 1U);

  // Simulate the render frame host is put into the back/forward cache
  render_frame_host()->DidEnterBackForwardCache();
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kInBackForwardCache));
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);

  // Trigger a permission status change event.
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::ASK);

  // Now the change events should not should increment the counter.
  EXPECT_EQ(observer->change_event_count(), 2U);
  EXPECT_EQ(observer_child->change_event_count(), 1U);

  // Simulate the render frame host is back to active state by setting the
  // lifecycle state.
  render_frame_host()->SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kActive);
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);

  // Since the render frame host is active, the dispatched events should
  // increment the counter.
  EXPECT_EQ(observer->change_event_count(), 3U);
  EXPECT_EQ(observer_child->change_event_count(), 2U);
}

TEST_F(PermissionServiceContextTest,
       DispatchMultiplePermissionChangeEventsInBackForwardCache) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is put into the back/forward cache.
  // Trigger a permission status change event, the event should not should
  // increment the counter.
  render_frame_host()->DidEnterBackForwardCache();
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kInBackForwardCache));

  for (size_t i = 0; i < 10; ++i) {
    SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                   blink::mojom::PermissionStatus::ASK);
    EXPECT_EQ(observer->change_event_count(), 0U);
    SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                   blink::mojom::PermissionStatus::DENIED);
    EXPECT_EQ(observer->change_event_count(), 0U);
  }

  // Simulate the render frame host is back to active state by setting the
  // lifecycle state. The last event should be dispatched and increment the
  // counter.
  render_frame_host()->SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kActive);
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  WaitForAsyncTasksToComplete();
  EXPECT_EQ(observer->change_event_count(), 1U);
}

TEST_F(PermissionServiceContextTest, CreateSubscriptionInBackForwardCache) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  render_frame_host()->DidEnterBackForwardCache();
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kInBackForwardCache));

  // Create a subscription in BFCache
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);
  EXPECT_EQ(observer->change_event_count(), 0U);
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::GRANTED);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is back to active state by setting the
  // lifecycle state. The last event should be dispatched.
  render_frame_host()->SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kActive);
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  WaitForAsyncTasksToComplete();
  EXPECT_EQ(observer->change_event_count(), 1U);
}

TEST_F(PermissionServiceContextTest,
       DispatchSameStatusAfterLeaveBackForwardCache) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is put into the back/forward cache.
  // Trigger a permission status change event, the event should not should
  // increment the counter.
  render_frame_host()->DidEnterBackForwardCache();
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kInBackForwardCache));
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Permission status changes back to the status at BFCache entry
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is back to active state by setting the
  // lifecycle state. No event should be dispatched.
  render_frame_host()->SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kActive);
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  WaitForAsyncTasksToComplete();
  EXPECT_EQ(observer->change_event_count(), 0U);
}

TEST_F(PermissionServiceContextTest,
       DispatchDifferentStatusAfterLeaveBackForwardCache) {
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  auto observer = CreateSubscription(PermissionType::GEOLOCATION,
                                     blink::mojom::PermissionStatus::ASK,
                                     blink::mojom::PermissionStatus::ASK);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is put into the back/forward cache.
  // Trigger a permission status change event, the event should not should
  // increment the counter.
  render_frame_host()->DidEnterBackForwardCache();
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kInBackForwardCache));
  SimulatePermissionChangedEvent(blink::PermissionType::GEOLOCATION,
                                 blink::mojom::PermissionStatus::DENIED);
  EXPECT_EQ(observer->change_event_count(), 0U);

  // Simulate the render frame host is back to active state by setting the
  // lifecycle state. The last event should be dispatched.
  render_frame_host()->SetLifecycleState(
      RenderFrameHostImpl::LifecycleStateImpl::kActive);
  EXPECT_TRUE(render_frame_host()->IsInLifecycleState(
      RenderFrameHost::LifecycleState::kActive));
  WaitForAsyncTasksToComplete();
  EXPECT_EQ(observer->change_event_count(), 1U);
}

}  // namespace content
