// 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 "content/browser/conversions/conversion_manager_impl.h"

#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_forward.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/test/bind_test_util.h"
#include "base/time/clock.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "content/browser/conversions/conversion_report.h"
#include "content/browser/conversions/conversion_test_utils.h"
#include "content/browser/conversions/storable_conversion.h"
#include "content/browser/conversions/storable_impression.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace content {

namespace {

constexpr base::TimeDelta kExpiredReportOffset =
    base::TimeDelta::FromMinutes(2);

class ConstantStartupDelayPolicy : public ConversionPolicy {
 public:
  ConstantStartupDelayPolicy() = default;
  ~ConstantStartupDelayPolicy() override = default;

  base::Time GetReportTimeForExpiredReportAtStartup(
      base::Time now) const override {
    return now + kExpiredReportOffset;
  }
};

// Mock reporter that tracks reports being queued by the ConversionManager.
class TestConversionReporter
    : public ConversionManagerImpl::ConversionReporter {
 public:
  TestConversionReporter() = default;
  ~TestConversionReporter() override = default;

  // ConversionManagerImpl::ConversionReporter
  void AddReportsToQueue(
      std::vector<ConversionReport> reports,
      base::RepeatingCallback<void(int64_t)> report_sent_callback) override {
    num_reports_ += reports.size();
    last_conversion_id_ = *reports.back().conversion_id;
    last_report_time_ = reports.back().report_time;

    if (should_run_report_sent_callbacks_) {
      for (const auto& report : reports) {
        report_sent_callback.Run(*report.conversion_id);
      }
    }

    if (quit_closure_ && num_reports_ >= expected_num_reports_)
      std::move(quit_closure_).Run();
  }

  void ShouldRunReportSentCallbacks(bool should_run_report_sent_callbacks) {
    should_run_report_sent_callbacks_ = should_run_report_sent_callbacks;
  }

  size_t num_reports() { return num_reports_; }

  int64_t last_conversion_id() { return last_conversion_id_; }

  base::Time last_report_time() { return last_report_time_; }

  void WaitForNumReports(size_t expected_num_reports) {
    if (num_reports_ >= expected_num_reports)
      return;

    expected_num_reports_ = expected_num_reports;
    base::RunLoop wait_loop;
    quit_closure_ = wait_loop.QuitClosure();
    wait_loop.Run();
  }

 private:
  bool should_run_report_sent_callbacks_ = false;
  size_t expected_num_reports_ = 0u;
  size_t num_reports_ = 0u;
  int64_t last_conversion_id_ = 0UL;
  base::Time last_report_time_;
  base::OnceClosure quit_closure_;
};

// Time after impression that a conversion can first be sent. See
// ConversionStorageDelegateImpl::GetReportTimeForConversion().
constexpr base::TimeDelta kFirstReportingWindow = base::TimeDelta::FromDays(2);

// Give impressions a sufficiently long expiry.
constexpr base::TimeDelta kImpressionExpiry = base::TimeDelta::FromDays(30);

}  // namespace

class ConversionManagerImplTest : public testing::Test {
 public:
  ConversionManagerImplTest()
      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
    EXPECT_TRUE(dir_.CreateUniqueTempDir());
    CreateManager();
  }

  void CreateManager() {
    auto reporter = std::make_unique<TestConversionReporter>();
    test_reporter_ = reporter.get();
    conversion_manager_ = ConversionManagerImpl::CreateForTesting(
        std::move(reporter), std::make_unique<ConstantStartupDelayPolicy>(),
        task_environment_.GetMockClock(), dir_.GetPath(),
        base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}));
  }

  const base::Clock& clock() { return *task_environment_.GetMockClock(); }

 protected:
  base::ScopedTempDir dir_;
  BrowserTaskEnvironment task_environment_;
  std::unique_ptr<ConversionManagerImpl> conversion_manager_;
  TestConversionReporter* test_reporter_ = nullptr;
};

TEST_F(ConversionManagerImplTest, ImpressionRegistered_ReturnedToWebUI) {
  auto impression = ImpressionBuilder(clock().Now())
                        .SetExpiry(kImpressionExpiry)
                        .SetData("100")
                        .Build();
  conversion_manager_->HandleImpression(impression);

  base::RunLoop run_loop;
  auto get_impressions_callback = base::BindLambdaForTesting(
      [&](std::vector<StorableImpression> impressions) {
        EXPECT_EQ(1u, impressions.size());
        EXPECT_TRUE(ImpressionsEqual(impression, impressions.back()));
        run_loop.Quit();
      });
  conversion_manager_->GetActiveImpressionsForWebUI(
      std::move(get_impressions_callback));
  run_loop.Run();
}

TEST_F(ConversionManagerImplTest, ExpiredImpression_NotReturnedToWebUI) {
  conversion_manager_->HandleImpression(ImpressionBuilder(clock().Now())
                                            .SetExpiry(kImpressionExpiry)
                                            .SetData("100")
                                            .Build());
  task_environment_.FastForwardBy(2 * kImpressionExpiry);

  base::RunLoop run_loop;
  auto get_impressions_callback = base::BindLambdaForTesting(
      [&](std::vector<StorableImpression> impressions) {
        EXPECT_TRUE(impressions.empty());
        run_loop.Quit();
      });
  conversion_manager_->GetActiveImpressionsForWebUI(
      std::move(get_impressions_callback));
  run_loop.Run();
}

TEST_F(ConversionManagerImplTest, ImpressionConverted_ReportReturnedToWebUI) {
  auto impression = ImpressionBuilder(clock().Now())
                        .SetExpiry(kImpressionExpiry)
                        .SetData("100")
                        .Build();
  conversion_manager_->HandleImpression(impression);

  auto conversion = DefaultConversion();
  conversion_manager_->HandleConversion(conversion);

  ConversionReport expected_report(impression, conversion.conversion_data(),
                                   clock().Now() + kFirstReportingWindow,
                                   base::nullopt /* conversion_id */);
  expected_report.attribution_credit = 100;

  base::RunLoop run_loop;
  auto reports_callback =
      base::BindLambdaForTesting([&](std::vector<ConversionReport> reports) {
        EXPECT_EQ(1u, reports.size());
        EXPECT_TRUE(ReportsEqual({expected_report}, reports));
        run_loop.Quit();
      });
  conversion_manager_->GetReportsForWebUI(std::move(reports_callback),
                                          base::Time::Max());
  run_loop.Run();
}

TEST_F(ConversionManagerImplTest, ImpressionConverted_ReportQueued) {
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());

  // Reports are queued in intervals ahead of when they should be
  // sent. Make sure the report is not queued earlier than this.
  task_environment_.FastForwardBy(kFirstReportingWindow -
                                  kConversionManagerQueueReportsInterval -
                                  base::TimeDelta::FromMinutes(1));
  EXPECT_EQ(0u, test_reporter_->num_reports());

  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
  EXPECT_EQ(1u, test_reporter_->num_reports());
}

TEST_F(ConversionManagerImplTest, QueuedReportNotSent_QueuedAgain) {
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());
  task_environment_.FastForwardBy(kFirstReportingWindow -
                                  kConversionManagerQueueReportsInterval);
  EXPECT_EQ(1u, test_reporter_->num_reports());

  // If the report is not sent, it should be added to the queue again.
  task_environment_.FastForwardBy(kConversionManagerQueueReportsInterval);
  EXPECT_EQ(2u, test_reporter_->num_reports());
}

TEST_F(ConversionManagerImplTest, QueuedReportSent_NotQueuedAgain) {
  test_reporter_->ShouldRunReportSentCallbacks(true);
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());
  task_environment_.FastForwardBy(kFirstReportingWindow -
                                  kConversionManagerQueueReportsInterval);
  EXPECT_EQ(1u, test_reporter_->num_reports());

  // The report should not be added to the queue again.
  task_environment_.FastForwardBy(kConversionManagerQueueReportsInterval);
  EXPECT_EQ(1u, test_reporter_->num_reports());
}

// Add a conversion to storage and reset the manager to mimic a report being
// available at startup.
TEST_F(ConversionManagerImplTest, ExpiredReportsAtStartup_Queued) {
  // Create a report that will be reported at t= 2 days.
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());

  // Create another conversion that will be reported at t=
  // (kFirstReportingWindow + 2 * kConversionManagerQueueReportsInterval).
  task_environment_.FastForwardBy(2 * kConversionManagerQueueReportsInterval);
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());

  EXPECT_EQ(0u, test_reporter_->num_reports());

  // Reset the manager to simulate shutdown.
  conversion_manager_.reset();

  // Fast forward past the expected report time of the first conversion, t =
  // (kFirstReportingWindow+ 1 minute).
  task_environment_.FastForwardBy(kFirstReportingWindow -
                                  (2 * kConversionManagerQueueReportsInterval) +
                                  base::TimeDelta::FromMinutes(1));

  // Create the manager and check that the first report is queued immediately.
  CreateManager();
  test_reporter_->ShouldRunReportSentCallbacks(true);
  test_reporter_->WaitForNumReports(1);
  EXPECT_EQ(1u, test_reporter_->num_reports());

  // The second report is still queued at the correct time.
  task_environment_.FastForwardBy(kConversionManagerQueueReportsInterval);
  EXPECT_EQ(2u, test_reporter_->num_reports());
}

// This functionality is tested more thoroughly in the ConversionStorageSql
// unit tests. Here, just test to make sure the basic control flow is working.
TEST_F(ConversionManagerImplTest, ClearData) {
  for (bool match_url : {true, false}) {
    base::Time start = clock().Now();
    conversion_manager_->HandleImpression(
        ImpressionBuilder(start).SetExpiry(kImpressionExpiry).Build());
    conversion_manager_->HandleConversion(DefaultConversion());

    base::RunLoop run_loop;
    conversion_manager_->ClearData(
        start, start + base::TimeDelta::FromMinutes(1),
        base::BindLambdaForTesting(
            [match_url](const url::Origin& _) { return match_url; }),
        run_loop.QuitClosure());
    run_loop.Run();

    task_environment_.FastForwardBy(kFirstReportingWindow -
                                    kConversionManagerQueueReportsInterval);
    size_t expected_reports = match_url ? 0u : 1u;
    EXPECT_EQ(expected_reports, test_reporter_->num_reports());
  }
}

TEST_F(ConversionManagerImplTest, ConversionsSentFromUI_ReportedImmediately) {
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());
  EXPECT_EQ(0u, test_reporter_->num_reports());

  conversion_manager_->SendReportsForWebUI(base::DoNothing());
  task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(0));
  EXPECT_EQ(2u, test_reporter_->num_reports());
}

// TODO(crbug.com/1088449): Flaky on Linux and Android.
#if defined(OS_LINUX) || defined(OS_ANDROID)
#define MAYBE_ExpiredReportsAtStartup_Delayed \
  DISABLED_ExpiredReportsAtStartup_Delayed
#else
#define MAYBE_ExpiredReportsAtStartup_Delayed ExpiredReportsAtStartup_Delayed
#endif
TEST_F(ConversionManagerImplTest, MAYBE_ExpiredReportsAtStartup_Delayed) {
  // Create a report that will be reported at t= 2 days.
  base::Time start_time = clock().Now();
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());
  EXPECT_EQ(0u, test_reporter_->num_reports());

  // Reset the manager to simulate shutdown.
  conversion_manager_.reset();

  // Fast forward past the expected report time of the first conversion, t =
  // (kFirstReportingWindow+ 1 minute).
  task_environment_.FastForwardBy(kFirstReportingWindow +
                                  base::TimeDelta::FromMinutes(1));

  CreateManager();
  test_reporter_->WaitForNumReports(1);

  // Ensure that the expired report is delayed based on the time the browser
  // started.
  EXPECT_EQ(start_time + kFirstReportingWindow +
                base::TimeDelta::FromMinutes(1) + kExpiredReportOffset,
            test_reporter_->last_report_time());
}

TEST_F(ConversionManagerImplTest, NonExpiredReportsQueuedAtStartup_NotDelayed) {
  // Create a report that will be reported at t= 2 days.
  base::Time start_time = clock().Now();
  conversion_manager_->HandleImpression(
      ImpressionBuilder(clock().Now()).SetExpiry(kImpressionExpiry).Build());
  conversion_manager_->HandleConversion(DefaultConversion());
  EXPECT_EQ(0u, test_reporter_->num_reports());

  // Reset the manager to simulate shutdown.
  conversion_manager_.reset();

  // Fast forward just before the expected report time.
  task_environment_.FastForwardBy(kFirstReportingWindow -
                                  base::TimeDelta::FromMinutes(1));

  // Ensure that this report does not receive additional delay.
  CreateManager();
  test_reporter_->WaitForNumReports(1);
  EXPECT_EQ(1u, test_reporter_->num_reports());
  EXPECT_EQ(start_time + kFirstReportingWindow,
            test_reporter_->last_report_time());
}

}  // namespace content
