// Copyright 2017 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 "net/reporting/reporting_delivery_agent.h"

#include <map>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/time/tick_clock.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_delegate.h"
#include "net/reporting/reporting_endpoint_manager.h"
#include "net/reporting/reporting_observer.h"
#include "net/reporting/reporting_report.h"
#include "net/reporting/reporting_uploader.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace net {

namespace {

void SerializeReports(const std::vector<const ReportingReport*>& reports,
                      base::TimeTicks now,
                      std::string* json_out) {
  base::ListValue reports_value;

  for (const ReportingReport* report : reports) {
    std::unique_ptr<base::DictionaryValue> report_value =
        std::make_unique<base::DictionaryValue>();

    report_value->SetInteger("age", (now - report->queued).InMilliseconds());
    report_value->SetString("type", report->type);
    report_value->SetString("url", report->url.spec());
    report_value->SetString("user_agent", report->user_agent);
    report_value->SetKey("body", report->body->Clone());

    reports_value.Append(std::move(report_value));
  }

  bool json_written = base::JSONWriter::Write(reports_value, json_out);
  DCHECK(json_written);
}

class ReportingDeliveryAgentImpl : public ReportingDeliveryAgent,
                                   public ReportingObserver {
 public:
  ReportingDeliveryAgentImpl(ReportingContext* context)
      : context_(context),
        timer_(std::make_unique<base::OneShotTimer>()),
        weak_factory_(this) {
    context_->AddObserver(this);
  }

  // ReportingDeliveryAgent implementation:

  ~ReportingDeliveryAgentImpl() override { context_->RemoveObserver(this); }

  void SetTimerForTesting(std::unique_ptr<base::OneShotTimer> timer) override {
    DCHECK(!timer_->IsRunning());
    timer_ = std::move(timer);
  }

  // ReportingObserver implementation:
  void OnCacheUpdated() override {
    if (CacheHasReports() && !timer_->IsRunning()) {
      SendReports();
      StartTimer();
    }
  }

 private:
  using OriginGroup = std::pair<url::Origin, std::string>;
  using OriginEndpoint = std::pair<url::Origin, GURL>;

  class Delivery {
   public:
    Delivery(const OriginEndpoint& report_origin_endpoint)
        : report_origin(report_origin_endpoint.first),
          endpoint(report_origin_endpoint.second) {}

    ~Delivery() = default;

    void AddReports(const ReportingClient* client,
                    const std::vector<const ReportingReport*>& to_add) {
      reports_per_client[client->origin][client->endpoint] += to_add.size();
      reports.insert(reports.end(), to_add.begin(), to_add.end());
    }

    const url::Origin report_origin;
    const GURL endpoint;
    std::vector<const ReportingReport*> reports;
    std::map<url::Origin, std::map<GURL, int>> reports_per_client;
  };

  bool CacheHasReports() {
    std::vector<const ReportingReport*> reports;
    context_->cache()->GetReports(&reports);
    return !reports.empty();
  }

  void StartTimer() {
    timer_->Start(FROM_HERE, policy().delivery_interval,
                  base::BindRepeating(&ReportingDeliveryAgentImpl::OnTimerFired,
                                      base::Unretained(this)));
  }

  void OnTimerFired() {
    if (CacheHasReports()) {
      SendReports();
      StartTimer();
    }
  }

  void SendReports() {
    std::vector<const ReportingReport*> reports;
    cache()->GetNonpendingReports(&reports);

    // Mark all of these reports as pending, so that they're not deleted out
    // from under us while we're checking permissions (possibly on another
    // thread).
    cache()->SetReportsPending(reports);

    // First determine which origins we're allowed to upload reports about.
    std::set<url::Origin> report_origins;
    for (const ReportingReport* report : reports) {
      report_origins.insert(url::Origin::Create(report->url));
    }
    delegate()->CanSendReports(
        std::move(report_origins),
        base::BindOnce(&ReportingDeliveryAgentImpl::OnSendPermissionsChecked,
                       weak_factory_.GetWeakPtr(), std::move(reports)));
  }

  void OnSendPermissionsChecked(std::vector<const ReportingReport*> reports,
                                std::set<url::Origin> allowed_report_origins) {
    // Sort reports into (origin, group) buckets.
    std::map<OriginGroup, std::vector<const ReportingReport*>>
        origin_group_reports;
    for (const ReportingReport* report : reports) {
      url::Origin report_origin = url::Origin::Create(report->url);
      if (allowed_report_origins.find(report_origin) ==
          allowed_report_origins.end())
        continue;
      OriginGroup origin_group(report_origin, report->group);
      origin_group_reports[origin_group].push_back(report);
    }

    // Find an endpoint for each (origin, group) bucket and sort reports into
    // endpoint buckets. Don't allow concurrent deliveries to the same (origin,
    // group) bucket.
    std::map<OriginEndpoint, std::unique_ptr<Delivery>> deliveries;
    for (auto& it : origin_group_reports) {
      const OriginGroup& origin_group = it.first;
      const url::Origin& report_origin = origin_group.first;
      const std::string& group = origin_group.second;

      if (base::ContainsKey(pending_origin_groups_, origin_group))
        continue;

      const ReportingClient* client =
          endpoint_manager()->FindClientForOriginAndGroup(report_origin, group);
      if (client == nullptr) {
        continue;
      }
      cache()->MarkClientUsed(client);
      OriginEndpoint report_origin_endpoint(report_origin, client->endpoint);

      Delivery* delivery;
      auto delivery_it = deliveries.find(report_origin_endpoint);
      if (delivery_it == deliveries.end()) {
        auto new_delivery = std::make_unique<Delivery>(report_origin_endpoint);
        delivery = new_delivery.get();
        deliveries[report_origin_endpoint] = std::move(new_delivery);
      } else {
        delivery = delivery_it->second.get();
      }

      delivery->AddReports(client, it.second);
      pending_origin_groups_.insert(origin_group);
    }

    // Keep track of which of these reports we don't queue for delivery; we'll
    // need to mark them as not-pending.
    std::unordered_set<const ReportingReport*> undelivered_reports(
        reports.begin(), reports.end());

    // Start an upload for each delivery.
    for (auto& it : deliveries) {
      const OriginEndpoint& report_origin_endpoint = it.first;
      const url::Origin& report_origin = report_origin_endpoint.first;
      const GURL& endpoint = report_origin_endpoint.second;
      std::unique_ptr<Delivery>& delivery = it.second;

      std::string json;
      SerializeReports(delivery->reports, tick_clock()->NowTicks(), &json);

      int max_depth = 0;
      for (const ReportingReport* report : delivery->reports) {
        undelivered_reports.erase(report);
        if (report->depth > max_depth)
          max_depth = report->depth;
      }

      // TODO: Calculate actual max depth.
      uploader()->StartUpload(
          report_origin, endpoint, json, max_depth,
          base::BindOnce(&ReportingDeliveryAgentImpl::OnUploadComplete,
                         weak_factory_.GetWeakPtr(), std::move(delivery)));
    }

    cache()->ClearReportsPending(
        {undelivered_reports.begin(), undelivered_reports.end()});
  }

  void OnUploadComplete(std::unique_ptr<Delivery> delivery,
                        ReportingUploader::Outcome outcome) {
    for (const auto& origin_and_pair : delivery->reports_per_client) {
      const url::Origin& client_origin = origin_and_pair.first;
      for (const auto& endpoint_and_count : origin_and_pair.second) {
        const GURL& endpoint = endpoint_and_count.first;
        int report_count = endpoint_and_count.second;
        cache()->IncrementEndpointDeliveries(
            client_origin, endpoint, report_count,
            outcome == ReportingUploader::Outcome::SUCCESS);
      }
    }

    if (outcome == ReportingUploader::Outcome::SUCCESS) {
      cache()->RemoveReports(delivery->reports,
                             ReportingReport::Outcome::DELIVERED);
      endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, true);
    } else {
      cache()->IncrementReportsAttempts(delivery->reports);
      endpoint_manager()->InformOfEndpointRequest(delivery->endpoint, false);
    }

    if (outcome == ReportingUploader::Outcome::REMOVE_ENDPOINT)
      cache()->RemoveClientsForEndpoint(delivery->endpoint);

    for (const ReportingReport* report : delivery->reports) {
      pending_origin_groups_.erase(
          OriginGroup(delivery->report_origin, report->group));
    }

    cache()->ClearReportsPending(delivery->reports);
  }

  const ReportingPolicy& policy() { return context_->policy(); }
  const base::TickClock* tick_clock() { return context_->tick_clock(); }
  ReportingDelegate* delegate() { return context_->delegate(); }
  ReportingCache* cache() { return context_->cache(); }
  ReportingUploader* uploader() { return context_->uploader(); }
  ReportingEndpointManager* endpoint_manager() {
    return context_->endpoint_manager();
  }

  ReportingContext* context_;

  std::unique_ptr<base::OneShotTimer> timer_;

  // Tracks OriginGroup tuples for which there is a pending delivery running.
  // (Would be an unordered_set, but there's no hash on pair.)
  std::set<OriginGroup> pending_origin_groups_;

  base::WeakPtrFactory<ReportingDeliveryAgentImpl> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ReportingDeliveryAgentImpl);
};

}  // namespace

// static
std::unique_ptr<ReportingDeliveryAgent> ReportingDeliveryAgent::Create(
    ReportingContext* context) {
  return std::make_unique<ReportingDeliveryAgentImpl>(context);
}

ReportingDeliveryAgent::~ReportingDeliveryAgent() = default;

}  // namespace net
