// Copyright 2020 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 "components/net_log/net_log_proxy_source.h"

#include "base/run_loop.h"
#include "base/synchronization/lock.h"
#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h"
#include "net/log/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class FakeNetLogProxySink : public network::mojom::NetLogProxySink {
 public:
  FakeNetLogProxySink(mojo::PendingReceiver<network::mojom::NetLogProxySink>
                          proxy_sink_receiver,
                      int expected_number_of_events)
      : proxy_sink_receiver_(this, std::move(proxy_sink_receiver)),
        run_loop_quit_after_count_(expected_number_of_events) {}
  FakeNetLogProxySink(const FakeNetLogProxySink&) = delete;
  FakeNetLogProxySink& operator=(const FakeNetLogProxySink&) = delete;

  struct ProxiedEntry {
    ProxiedEntry(uint32_t type,
                 uint32_t source_type,
                 uint32_t source_id,
                 base::TimeTicks source_start_time,
                 net::NetLogEventPhase phase,
                 base::TimeTicks time,
                 base::Value params)
        : type(type),
          source_type(source_type),
          source_id(source_id),
          source_start_time(source_start_time),
          phase(phase),
          time(time),
          params(std::move(params)) {}

    ProxiedEntry(const ProxiedEntry& other)
        : ProxiedEntry(other.type,
                       other.source_type,
                       other.source_id,
                       other.source_start_time,
                       other.phase,
                       other.time,
                       other.params.Clone()) {}

    uint32_t type;
    uint32_t source_type;
    uint32_t source_id;
    base::TimeTicks source_start_time;
    net::NetLogEventPhase phase;
    base::TimeTicks time;
    base::Value params;
  };

  std::vector<ProxiedEntry> entries() const {
    base::AutoLock lock(lock_);
    return entries_;
  }

  void WaitForExpectedEntries() { run_loop_.Run(); }

  // mojom::NetLogProxySink:
  void AddEntry(uint32_t type,
                uint32_t source_type,
                uint32_t source_id,
                base::TimeTicks source_start_time,
                net::NetLogEventPhase phase,
                base::TimeTicks time,
                base::Value params) override {
    base::AutoLock lock(lock_);
    entries_.emplace_back(type, source_type, source_id, source_start_time,
                          phase, time, std::move(params));
    run_loop_quit_after_count_--;
    EXPECT_LE(0, run_loop_quit_after_count_);
    if (run_loop_quit_after_count_ == 0)
      run_loop_.Quit();
  }

 private:
  mutable base::Lock lock_;
  std::vector<ProxiedEntry> entries_;
  mojo::Receiver<network::mojom::NetLogProxySink> proxy_sink_receiver_;

  int run_loop_quit_after_count_;
  base::RunLoop run_loop_;
};

class NetLogCaptureModeWaiter
    : public net::NetLog::ThreadSafeCaptureModeObserver {
 public:
  explicit NetLogCaptureModeWaiter(
      const std::vector<net::NetLogCaptureModeSet>& expected_modes)
      : expected_modes_(expected_modes) {
    net::NetLog::Get()->AddCaptureModeObserver(this);
  }

  ~NetLogCaptureModeWaiter() override {
    net::NetLog::Get()->RemoveCaptureModeObserver(this);
  }

  void WaitForCaptureModeUpdate() { run_loop_.Run(); }

  // net::NetLog::ThreadSafeCaptureModeObserver:
  void OnCaptureModeUpdated(net::NetLogCaptureModeSet modes) override {
    ASSERT_FALSE(expected_modes_.empty())
        << "NetLogCaptureModeWaiter called too many times, modes = " << modes;
    EXPECT_EQ(expected_modes_.front(), modes);
    expected_modes_.erase(expected_modes_.begin());
    if (expected_modes_.empty())
      run_loop_.Quit();
  }

 private:
  std::vector<net::NetLogCaptureModeSet> expected_modes_;
  base::RunLoop run_loop_;
};

base::Value NetLogCaptureModeToParams(net::NetLogCaptureMode capture_mode) {
  base::Value dict(base::Value::Type::DICTIONARY);
  switch (capture_mode) {
    case net::NetLogCaptureMode::kDefault:
      dict.SetStringKey("capture_mode", "kDefault");
      break;
    case net::NetLogCaptureMode::kIncludeSensitive:
      dict.SetStringKey("capture_mode", "kIncludeSensitive");
      break;
    case net::NetLogCaptureMode::kEverything:
      dict.SetStringKey("capture_mode", "kEverything");
      break;
  }
  return dict;
}

}  // namespace

TEST(NetLogProxySource, OnlyProxiesEventsWhenCaptureModeSetIsNonZero) {
  base::test::TaskEnvironment task_environment{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  const size_t kExpectedEventCount = 2;

  mojo::Remote<network::mojom::NetLogProxySource> proxy_source_remote;
  mojo::Remote<network::mojom::NetLogProxySink> proxy_sink_remote;
  FakeNetLogProxySink sink(proxy_sink_remote.BindNewPipeAndPassReceiver(),
                           kExpectedEventCount);
  net_log::NetLogProxySource net_log_source(
      proxy_source_remote.BindNewPipeAndPassReceiver(),
      std::move(proxy_sink_remote));

  // No capture modes are set, so should not get proxied.
  task_environment.FastForwardBy(base::TimeDelta::FromSeconds(9876));

  net::NetLogWithSource source0 = net::NetLogWithSource::Make(
      net::NetLog::Get(), net::NetLogSourceType::URL_REQUEST);
  source0.BeginEvent(net::NetLogEventType::REQUEST_ALIVE);

  auto capture_mode_waiter = std::make_unique<NetLogCaptureModeWaiter>(
      std::vector<net::NetLogCaptureModeSet>{net::NetLogCaptureModeToBit(
          net::NetLogCaptureMode::kIncludeSensitive)});
  proxy_source_remote->UpdateCaptureModes(
      net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive));
  // Wait for the mojo message to be delivered and the NetLogProxySource to
  // start listening for NetLog events.
  capture_mode_waiter->WaitForCaptureModeUpdate();

  task_environment.FastForwardBy(base::TimeDelta::FromSeconds(5432));
  base::TimeTicks source1_start_ticks = base::TimeTicks::Now();

  net::NetLogWithSource source1 = net::NetLogWithSource::Make(
      net::NetLog::Get(), net::NetLogSourceType::SOCKET);
  task_environment.FastForwardBy(base::TimeDelta::FromSeconds(1));
  base::TimeTicks source1_event0_ticks = base::TimeTicks::Now();
  source1.BeginEvent(net::NetLogEventType::SOCKET_ALIVE);

  task_environment.FastForwardBy(base::TimeDelta::FromSeconds(10));
  base::TimeTicks source1_event1_ticks = base::TimeTicks::Now();
  // Add the second event from a different thread. Use a lambda instead of
  // binding to NetLogWithSource::EndEvent since EndEvent is overloaded and
  // templatized which seems to confuse BindOnce. Capturing is safe here as
  // the test will WaitForExpectedEntries() before completing.
  base::ThreadPool::PostTask(
      FROM_HERE, base::BindOnce(base::BindLambdaForTesting([&]() {
        source1.EndEvent(net::NetLogEventType::SOCKET_ALIVE);
      })));

  // Wait for all the expected events to be proxied over the mojo pipe and
  // recorded.
  sink.WaitForExpectedEntries();

  capture_mode_waiter = std::make_unique<NetLogCaptureModeWaiter>(
      std::vector<net::NetLogCaptureModeSet>{0});
  proxy_source_remote->UpdateCaptureModes(0);
  // Wait for the mojo message to be delivered and the NetLogProxySource to
  // stop listening for NetLog events.
  capture_mode_waiter->WaitForCaptureModeUpdate();

  // No capture modes are set, so should not get proxied.
  net::NetLog::Get()->AddGlobalEntry(net::NetLogEventType::CANCELLED);

  // Run any remaining tasks, just in case there any unexpected events getting
  // proxied, this should give them a chance to get recorded so the test would
  // fail.
  task_environment.RunUntilIdle();

  const auto& entries = sink.entries();
  ASSERT_EQ(kExpectedEventCount, entries.size());

  EXPECT_EQ(static_cast<uint32_t>(net::NetLogEventType::SOCKET_ALIVE),
            entries[0].type);
  EXPECT_EQ(static_cast<uint32_t>(net::NetLogSourceType::SOCKET),
            entries[0].source_type);
  EXPECT_EQ(source1.source().id, entries[0].source_id);
  EXPECT_EQ(source1_start_ticks, entries[0].source_start_time);
  EXPECT_EQ(net::NetLogEventPhase::BEGIN, entries[0].phase);
  EXPECT_EQ(source1_event0_ticks, entries[0].time);
  EXPECT_TRUE(entries[0].params.is_none());

  EXPECT_EQ(static_cast<uint32_t>(net::NetLogEventType::SOCKET_ALIVE),
            entries[1].type);
  EXPECT_EQ(static_cast<uint32_t>(net::NetLogSourceType::SOCKET),
            entries[1].source_type);
  EXPECT_EQ(source1.source().id, entries[1].source_id);
  EXPECT_EQ(source1_start_ticks, entries[1].source_start_time);
  EXPECT_EQ(net::NetLogEventPhase::END, entries[1].phase);
  EXPECT_EQ(source1_event1_ticks, entries[1].time);
  EXPECT_TRUE(entries[1].params.is_none());
}

TEST(NetLogProxySource, ProxiesParamsOfLeastSensitiveCaptureMode) {
  base::test::TaskEnvironment task_environment;

  const size_t kExpectedEventCount = 3;

  mojo::Remote<network::mojom::NetLogProxySource> proxy_source_remote;
  mojo::Remote<network::mojom::NetLogProxySink> proxy_sink_remote;
  FakeNetLogProxySink sink(proxy_sink_remote.BindNewPipeAndPassReceiver(),
                           kExpectedEventCount);
  net_log::NetLogProxySource net_log_source(
      proxy_source_remote.BindNewPipeAndPassReceiver(),
      std::move(proxy_sink_remote));
  net::NetLogWithSource source0 = net::NetLogWithSource::Make(
      net::NetLog::Get(), net::NetLogSourceType::URL_REQUEST);

  auto capture_mode_waiter = std::make_unique<NetLogCaptureModeWaiter>(
      std::vector<net::NetLogCaptureModeSet>{net::NetLogCaptureModeToBit(
          net::NetLogCaptureMode::kIncludeSensitive)});
  proxy_source_remote->UpdateCaptureModes(
      net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive));
  // Wait for the mojo message to be delivered and the NetLogProxySource to
  // start listening for NetLog events.
  capture_mode_waiter->WaitForCaptureModeUpdate();
  source0.BeginEvent(net::NetLogEventType::REQUEST_ALIVE,
                     &NetLogCaptureModeToParams);

  capture_mode_waiter = std::make_unique<NetLogCaptureModeWaiter>(
      std::vector<net::NetLogCaptureModeSet>{
          0, net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kDefault)});
  proxy_source_remote->UpdateCaptureModes(
      net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kDefault) |
      net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kIncludeSensitive));
  // Wait for the mojo message to be delivered and the NetLogProxySource to
  // update the level it is listening for NetLog events.
  // Should be listening at the default level only, as that is the lowest
  // level in the capture mode set.
  capture_mode_waiter->WaitForCaptureModeUpdate();
  source0.AddEvent(net::NetLogEventType::FAILED, &NetLogCaptureModeToParams);

  proxy_source_remote->UpdateCaptureModes(
      net::NetLogCaptureModeToBit(net::NetLogCaptureMode::kDefault));
  // NetLogProxySource's observer capture mode shouldn't change, so can't use
  // NetLogCaptureModeWaiter here. Just run the task loops.
  task_environment.RunUntilIdle();
  source0.EndEvent(net::NetLogEventType::REQUEST_ALIVE,
                   &NetLogCaptureModeToParams);

  // Wait for all the expected events to be proxied over the mojo pipe and
  // recorded.
  sink.WaitForExpectedEntries();

  const auto& entries = sink.entries();
  ASSERT_EQ(kExpectedEventCount, entries.size());

  EXPECT_EQ(static_cast<uint32_t>(net::NetLogEventType::REQUEST_ALIVE),
            entries[0].type);
  EXPECT_EQ(static_cast<uint32_t>(net::NetLogSourceType::URL_REQUEST),
            entries[0].source_type);
  EXPECT_EQ(source0.source().id, entries[0].source_id);
  EXPECT_EQ(net::NetLogEventPhase::BEGIN, entries[0].phase);
  ASSERT_TRUE(entries[0].params.is_dict());
  EXPECT_EQ(1U, entries[0].params.DictSize());
  const std::string* param = entries[0].params.FindStringKey("capture_mode");
  ASSERT_TRUE(param);
  EXPECT_EQ("kIncludeSensitive", *param);

  EXPECT_EQ(static_cast<uint32_t>(net::NetLogEventType::FAILED),
            entries[1].type);
  EXPECT_EQ(static_cast<uint32_t>(net::NetLogSourceType::URL_REQUEST),
            entries[1].source_type);
  EXPECT_EQ(source0.source().id, entries[1].source_id);
  EXPECT_EQ(net::NetLogEventPhase::NONE, entries[1].phase);
  ASSERT_TRUE(entries[1].params.is_dict());
  EXPECT_EQ(1U, entries[1].params.DictSize());
  param = entries[1].params.FindStringKey("capture_mode");
  ASSERT_TRUE(param);
  EXPECT_EQ("kDefault", *param);

  EXPECT_EQ(static_cast<uint32_t>(net::NetLogEventType::REQUEST_ALIVE),
            entries[2].type);
  EXPECT_EQ(static_cast<uint32_t>(net::NetLogSourceType::URL_REQUEST),
            entries[2].source_type);
  EXPECT_EQ(source0.source().id, entries[2].source_id);
  EXPECT_EQ(net::NetLogEventPhase::END, entries[2].phase);
  ASSERT_TRUE(entries[2].params.is_dict());
  EXPECT_EQ(1U, entries[2].params.DictSize());
  param = entries[2].params.FindStringKey("capture_mode");
  ASSERT_TRUE(param);
  EXPECT_EQ("kDefault", *param);
}
