// 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_reporter_impl.h"

#include "base/bind.h"
#include "base/callback.h"
#include "base/rand_util.h"
#include "base/time/clock.h"
#include "content/browser/conversions/conversion_manager.h"
#include "content/browser/conversions/conversion_network_sender_impl.h"

namespace content {

ConversionReporterImpl::ConversionReporterImpl(
    StoragePartition* storage_partition,
    ConversionManager* conversion_manager,
    const base::Clock* clock)
    : conversion_manager_(conversion_manager),
      clock_(clock),
      network_sender_(
          std::make_unique<ConversionNetworkSenderImpl>(storage_partition)) {
  DCHECK(conversion_manager_);
}

ConversionReporterImpl::~ConversionReporterImpl() = default;

void ConversionReporterImpl::AddReportsToQueue(
    std::vector<ConversionReport> reports) {
  DCHECK(!reports.empty());

  std::vector<std::unique_ptr<ConversionReport>> swappable_reports;
  for (ConversionReport& report : reports) {
    swappable_reports.push_back(
        std::make_unique<ConversionReport>(std::move(report)));
  }

  // Shuffle new reports to provide plausible deniability on the ordering of
  // reports that share the same |report_time|. This is important because
  // multiple conversions for the same impression share the same report time if
  // they are within the same reporting window, and we do not want to allow
  // ordering on their conversion metadata bits.
  base::RandomShuffle(swappable_reports.begin(), swappable_reports.end());

  for (std::unique_ptr<ConversionReport>& report : swappable_reports) {
    // If the given report is already being processed, ignore it.
    bool inserted =
        conversion_ids_being_processed_.insert(*(report->conversion_id)).second;
    if (inserted)
      report_queue_.push(std::move(report));
  }
  MaybeScheduleNextReport();
}

void ConversionReporterImpl::SetNetworkSenderForTesting(
    std::unique_ptr<NetworkSender> network_sender) {
  network_sender_ = std::move(network_sender);
}

void ConversionReporterImpl::SendNextReport() {
  // Send the next report and remove it from the queue. Bind the conversion id
  // to the sent callback so we know which conversion report has finished
  // sending.
  network_sender_->SendReport(
      report_queue_.top().get(),
      base::BindOnce(&ConversionReporterImpl::OnReportSent,
                     base::Unretained(this),
                     *report_queue_.top()->conversion_id));
  report_queue_.pop();
  MaybeScheduleNextReport();
}

void ConversionReporterImpl::MaybeScheduleNextReport() {
  if (report_queue_.empty())
    return;

  send_report_timer_.Stop();
  base::Time current_time = clock_->Now();
  base::Time report_time = report_queue_.top()->report_time;

  // Start a timer to wait until the next report is ready to be sent. This
  // purposefully yields the thread for every report that gets scheduled.
  // Unretained is safe because the task should never actually be posted if the
  // timer itself is destroyed
  send_report_timer_.Start(
      FROM_HERE, report_time - current_time,
      base::BindOnce(&ConversionReporterImpl::SendNextReport,
                     base::Unretained(this)));
}

void ConversionReporterImpl::OnReportSent(int64_t conversion_id) {
  conversion_ids_being_processed_.erase(conversion_id);
  conversion_manager_->HandleSentReport(conversion_id);
}

bool ConversionReporterImpl::ReportComparator::operator()(
    const std::unique_ptr<ConversionReport>& a,
    const std::unique_ptr<ConversionReport>& b) const {
  // Returns whether a should appear before b in ordering. Because
  // std::priority_queue is max priority queue, we used greater then to make a
  // min priority queue.
  return a->report_time > b->report_time;
}

}  // namespace content
