// 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 "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/path_service.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_proto_loader.h"
#include "base/threading/thread_restrictions.h"
#include "base/token.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/browser/tracing/background_tracing_manager_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/tracing_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/test/browser_task_environment.h"
#include "net/base/network_change_notifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/zlib/google/compression_utils.h"

namespace content {

namespace {

const char kDummyTrace[] = "Trace bytes as serialized proto";

class MockNetworkChangeNotifier : public net::NetworkChangeNotifier {
 public:
  ConnectionType GetCurrentConnectionType() const override { return type_; }
  void set_type(ConnectionType type) { type_ = type; }

 private:
  ConnectionType type_;
};

class TestBackgroundTracingHelper
    : public BackgroundTracingManager::EnabledStateTestObserver {
 public:
  TestBackgroundTracingHelper() {
    BackgroundTracingManagerImpl::GetInstance()
        .AddEnabledStateObserverForTesting(this);
  }

  ~TestBackgroundTracingHelper() {
    BackgroundTracingManagerImpl::GetInstance()
        .RemoveEnabledStateObserverForTesting(this);
  }

  void OnTraceSaved() override { wait_for_trace_saved_.Quit(); }

  void WaitForTraceSaved() { wait_for_trace_saved_.Run(); }

 private:
  base::RunLoop wait_for_trace_saved_;
};

perfetto::protos::gen::ChromeFieldTracingConfig ParseFieldTracingConfigFromText(
    const std::string& proto_text) {
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::TestProtoLoader config_loader(
      base::PathService::CheckedGet(base::DIR_GEN_TEST_DATA_ROOT)
          .Append(
              FILE_PATH_LITERAL("third_party/perfetto/protos/perfetto/"
                                "config/chrome/scenario_config.descriptor")),
      "perfetto.protos.ChromeFieldTracingConfig");
  std::string serialized_message;
  config_loader.ParseFromText(proto_text, serialized_message);
  perfetto::protos::gen::ChromeFieldTracingConfig destination;
  destination.ParseFromString(serialized_message);
  return destination;
}

class MockBrowserClient : public content::ContentBrowserClient {
 public:
  MockBrowserClient(base::FilePath traces_dir) : traces_dir_(traces_dir) {}
  ~MockBrowserClient() override {}

  std::optional<base::FilePath> GetLocalTracesDirectory() override {
    return traces_dir_;
  }

 private:
  base::FilePath traces_dir_;
};

}  // namespace

class BackgroundTracingManagerTest : public testing::Test {
 public:
  BackgroundTracingManagerTest() {
    background_tracing_manager_ =
        std::make_unique<BackgroundTracingManagerImpl>(&tracing_delegate_);
  }

 protected:
  BrowserTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  content::TracingDelegate tracing_delegate_;
  std::unique_ptr<content::BackgroundTracingManagerImpl>
      background_tracing_manager_;
};

TEST_F(BackgroundTracingManagerTest, HasTraceToUpload) {
  background_tracing_manager_->SetUploadLimitsForTesting(2, 1);
  {
    std::string trace_content(1500, 'a');

    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        std::move(trace_content), "test_scenario", "test_rule",
        base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }

  MockNetworkChangeNotifier notifier;
  notifier.set_type(net::NetworkChangeNotifier::CONNECTION_2G);
#if BUILDFLAG(IS_ANDROID)
  EXPECT_FALSE(background_tracing_manager_->HasTraceToUpload());
#endif

  notifier.set_type(net::NetworkChangeNotifier::CONNECTION_WIFI);
  EXPECT_TRUE(background_tracing_manager_->HasTraceToUpload());
}

TEST_F(BackgroundTracingManagerTest, GetTraceToUpload) {
  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }

  EXPECT_TRUE(background_tracing_manager_->HasTraceToUpload());

  std::string compressed_trace;
  base::RunLoop run_loop;
  background_tracing_manager_->GetTraceToUpload(
      base::BindLambdaForTesting([&](std::optional<std::string> trace_content,
                                     std::optional<std::string> system_profile,
                                     base::OnceClosure upload_complete) {
        ASSERT_TRUE(trace_content);
        compressed_trace = std::move(*trace_content);
        std::move(upload_complete).Run();
        run_loop.Quit();
      }));
  run_loop.Run();

  std::string serialized_trace;
  ASSERT_TRUE(compression::GzipUncompress(compressed_trace, &serialized_trace));
  EXPECT_EQ(kDummyTrace, serialized_trace);

  EXPECT_FALSE(background_tracing_manager_->HasTraceToUpload());
}

TEST_F(BackgroundTracingManagerTest, SavedCountPreventsStart) {
  constexpr const char kScenarioConfig[] = R"pb(
    scenarios: {
      scenario_name: "test_scenario"
      start_rules: {
        name: "start_trigger"
        manual_trigger_name: "start_trigger"
      }
      trace_config: {
        data_sources: { config: { name: "org.chromium.trace_metadata2" } }
      }
    }
  )pb";

  constexpr size_t kNumSavedTraces = 200;
  for (size_t i = 0; i < kNumSavedTraces; ++i) {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_EQ(kNumSavedTraces,
            BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                "test_scenario"));

  background_tracing_manager_->InitializeFieldScenarios(
      ParseFieldTracingConfigFromText(kScenarioConfig),
      BackgroundTracingManager::NO_DATA_FILTERING, false, 0);

  EXPECT_FALSE(base::trace_event::EmitNamedTrigger("start_trigger"));
}

TEST_F(BackgroundTracingManagerTest, SavedCountAfterClean) {
  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_EQ(1U,
            BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                "test_scenario"));

  task_environment_.FastForwardBy(base::Days(15));

  EXPECT_EQ(0U,
            BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                "test_scenario"));
}

TEST_F(BackgroundTracingManagerTest, SavedCountAfterDelete) {
  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_EQ(1U,
            BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                "test_scenario"));
  background_tracing_manager_->DeleteTracesInDateRange(
      base::Time::Now() - base::Days(1), base::Time::Now());
  task_environment_.RunUntilIdle();

  EXPECT_EQ(0U,
            BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                "test_scenario"));
}

TEST_F(BackgroundTracingManagerTest, UploadScenarioQuotaExceeded) {
  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_TRUE(background_tracing_manager_->HasTraceToUpload());

  base::RunLoop run_loop;
  background_tracing_manager_->GetTraceToUpload(
      base::BindLambdaForTesting([&](std::optional<std::string> trace_content,
                                     std::optional<std::string> system_profile,
                                     base::OnceClosure upload_complete) {
        std::move(upload_complete).Run();
        run_loop.Quit();
      }));
  run_loop.Run();

  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_FALSE(background_tracing_manager_->HasTraceToUpload());
}

TEST_F(BackgroundTracingManagerTest, UploadScenarioQuotaReset) {
  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_TRUE(background_tracing_manager_->HasTraceToUpload());

  base::RunLoop run_loop;
  background_tracing_manager_->GetTraceToUpload(
      base::IgnoreArgs<std::optional<std::string>, std::optional<std::string>,
                       base::OnceClosure>(run_loop.QuitClosure()));
  run_loop.Run();

  task_environment_.FastForwardBy(base::Days(8));

  {
    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager_->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
  }
  EXPECT_TRUE(background_tracing_manager_->HasTraceToUpload());
}

TEST(BackgroundTracingManagerPersistentTest, DeleteTracesInDateRange) {
  BrowserTaskEnvironment task_environment{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  base::ScopedTempDir traces_dir;
  ASSERT_TRUE(traces_dir.CreateUniqueTempDir());
  content::ContentClient content_client;
  MockBrowserClient browser_client(traces_dir.GetPath());

  content::SetContentClient(&content_client);
  content::SetBrowserClientForTesting(&browser_client);

  {
    content::TracingDelegate tracing_delegate;
    std::unique_ptr<content::BackgroundTracingManager>
        background_tracing_manager =
            content::BackgroundTracingManager::CreateInstance(
                &tracing_delegate);
    BackgroundTracingManagerImpl::GetInstance().InitializeTraceReportDatabase();

    TestBackgroundTracingHelper background_tracing_helper;
    background_tracing_manager->SaveTraceForTesting(
        kDummyTrace, "test_scenario", "test_rule", base::Token::CreateRandom());
    background_tracing_helper.WaitForTraceSaved();
    EXPECT_EQ(1U,
              BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                  "test_scenario"));
  }
  // Ensure the database tear down completed.
  task_environment.RunUntilIdle();

  {
    content::TracingDelegate tracing_delegate;
    std::unique_ptr<content::BackgroundTracingManager>
        background_tracing_manager =
            content::BackgroundTracingManager::CreateInstance(
                &tracing_delegate);
    BackgroundTracingManagerImpl::GetInstance().InitializeTraceReportDatabase();
    task_environment.RunUntilIdle();
    EXPECT_EQ(1U,
              BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                  "test_scenario"));
  }
  // Ensure the database tear down completed.
  task_environment.RunUntilIdle();

  {
    content::TracingDelegate tracing_delegate;
    std::unique_ptr<content::BackgroundTracingManager>
        background_tracing_manager =
            content::BackgroundTracingManager::CreateInstance(
                &tracing_delegate);
    BackgroundTracingManagerImpl::GetInstance().InitializeTraceReportDatabase();

    auto now = base::Time::Now();
    background_tracing_manager->DeleteTracesInDateRange(now - base::Days(1),
                                                        now);
    task_environment.RunUntilIdle();
    EXPECT_EQ(0U,
              BackgroundTracingManagerImpl::GetInstance().GetScenarioSavedCount(
                  "test_scenario"));
  }

  content::SetBrowserClientForTesting(nullptr);
  content::SetContentClient(nullptr);
}

}  // namespace content
