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

#include <string>

#include "base/bind.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "net/reporting/reporting_cache.h"
#include "net/reporting/reporting_client.h"
#include "net/reporting/reporting_context.h"
#include "net/reporting/reporting_delegate.h"

namespace net {

namespace {

using HeaderEndpointGroupOutcome =
    ReportingHeaderParser::HeaderEndpointGroupOutcome;
using HeaderEndpointOutcome = ReportingHeaderParser::HeaderEndpointOutcome;
using HeaderOutcome = ReportingHeaderParser::HeaderOutcome;

void RecordHeaderOutcome(HeaderOutcome outcome) {
  UMA_HISTOGRAM_ENUMERATION(ReportingHeaderParser::kHeaderOutcomeHistogram,
                            outcome, HeaderOutcome::MAX);
}

void RecordHeaderEndpointGroupOutcome(HeaderEndpointGroupOutcome outcome) {
  UMA_HISTOGRAM_ENUMERATION(
      ReportingHeaderParser::kHeaderEndpointGroupOutcomeHistogram, outcome,
      HeaderEndpointGroupOutcome::MAX);
}

bool EndpointParsedSuccessfully(HeaderEndpointOutcome outcome) {
  return outcome == HeaderEndpointOutcome::REMOVED ||
         outcome == HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE ||
         outcome == HeaderEndpointOutcome::SET;
}

void RecordHeaderEndpointOutcome(HeaderEndpointOutcome outcome) {
  UMA_HISTOGRAM_ENUMERATION(
      ReportingHeaderParser::kHeaderEndpointOutcomeHistogram, outcome,
      HeaderEndpointOutcome::MAX);
}

const char kUrlKey[] = "url";
const char kIncludeSubdomainsKey[] = "include_subdomains";
const char kEndpointsKey[] = "endpoints";
const char kGroupKey[] = "group";
const char kGroupDefaultValue[] = "default";
const char kMaxAgeKey[] = "max_age";
const char kPriorityKey[] = "priority";
const char kWeightKey[] = "weight";

// Processes a single endpoint tuple received in a Report-To header.
//
// |origin| is the origin that sent the Report-To header.
//
// |value| is the parsed JSON value of the endpoint tuple.
//
// |*endpoint_out| will contain the endpoint URL parsed out of the tuple.
HeaderEndpointOutcome ProcessEndpoint(ReportingDelegate* delegate,
                                      ReportingCache* cache,
                                      base::TimeTicks now,
                                      const std::string& group,
                                      int ttl_sec,
                                      ReportingClient::Subdomains subdomains,
                                      const url::Origin& origin,
                                      const base::Value& value,
                                      GURL* endpoint_url_out) {
  *endpoint_url_out = GURL();

  const base::DictionaryValue* dict = nullptr;
  if (!value.GetAsDictionary(&dict))
    return HeaderEndpointOutcome::DISCARDED_NOT_DICTIONARY;
  DCHECK(dict);

  std::string endpoint_url_string;
  if (!dict->HasKey(kUrlKey))
    return HeaderEndpointOutcome::DISCARDED_URL_MISSING;
  if (!dict->GetString(kUrlKey, &endpoint_url_string))
    return HeaderEndpointOutcome::DISCARDED_URL_NOT_STRING;

  GURL endpoint_url(endpoint_url_string);
  if (!endpoint_url.is_valid())
    return HeaderEndpointOutcome::DISCARDED_URL_INVALID;
  if (!endpoint_url.SchemeIsCryptographic())
    return HeaderEndpointOutcome::DISCARDED_URL_INSECURE;

  int priority = ReportingClient::kDefaultPriority;
  if (dict->HasKey(kPriorityKey) && !dict->GetInteger(kPriorityKey, &priority))
    return HeaderEndpointOutcome::DISCARDED_PRIORITY_NOT_INTEGER;

  int weight = ReportingClient::kDefaultWeight;
  if (dict->HasKey(kWeightKey) && !dict->GetInteger(kWeightKey, &weight))
    return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_INTEGER;
  if (weight <= 0)
    return HeaderEndpointOutcome::DISCARDED_WEIGHT_NOT_POSITIVE;

  *endpoint_url_out = endpoint_url;

  if (ttl_sec == 0) {
    cache->RemoveClientForOriginAndEndpoint(origin, endpoint_url);
    return HeaderEndpointOutcome::REMOVED;
  }

  if (!delegate->CanSetClient(origin, endpoint_url))
    return HeaderEndpointOutcome::SET_REJECTED_BY_DELEGATE;

  cache->SetClient(origin, endpoint_url, subdomains, group,
                   now + base::TimeDelta::FromSeconds(ttl_sec), priority,
                   weight);
  return HeaderEndpointOutcome::SET;
}

// Processes a single endpoint group tuple received in a Report-To header.
//
// |origin| is the origin that sent the Report-To header.
//
// |value| is the parsed JSON value of the endpoint group tuple.
HeaderEndpointGroupOutcome ProcessEndpointGroup(ReportingDelegate* delegate,
                                                ReportingCache* cache,
                                                std::set<GURL>* new_endpoints,
                                                base::TimeTicks now,
                                                const url::Origin& origin,
                                                const base::Value& value) {
  const base::DictionaryValue* dict = nullptr;
  if (!value.GetAsDictionary(&dict))
    return HeaderEndpointGroupOutcome::DISCARDED_NOT_DICTIONARY;
  DCHECK(dict);

  std::string group = kGroupDefaultValue;
  if (dict->HasKey(kGroupKey) && !dict->GetString(kGroupKey, &group))
    return HeaderEndpointGroupOutcome::DISCARDED_GROUP_NOT_STRING;

  int ttl_sec = -1;
  if (!dict->HasKey(kMaxAgeKey))
    return HeaderEndpointGroupOutcome::DISCARDED_TTL_MISSING;
  if (!dict->GetInteger(kMaxAgeKey, &ttl_sec))
    return HeaderEndpointGroupOutcome::DISCARDED_TTL_NOT_INTEGER;
  if (ttl_sec < 0)
    return HeaderEndpointGroupOutcome::DISCARDED_TTL_NEGATIVE;

  ReportingClient::Subdomains subdomains = ReportingClient::Subdomains::EXCLUDE;
  bool subdomains_bool = false;
  if (dict->HasKey(kIncludeSubdomainsKey) &&
      dict->GetBoolean(kIncludeSubdomainsKey, &subdomains_bool) &&
      subdomains_bool == true) {
    subdomains = ReportingClient::Subdomains::INCLUDE;
  }

  const base::ListValue* endpoint_list = nullptr;
  if (!dict->HasKey(kEndpointsKey))
    return HeaderEndpointGroupOutcome::DISCARDED_ENDPOINTS_MISSING;
  if (!dict->GetList(kEndpointsKey, &endpoint_list))
    return HeaderEndpointGroupOutcome::DISCARDED_ENDPOINTS_NOT_LIST;

  for (size_t i = 0; i < endpoint_list->GetSize(); i++) {
    const base::Value* endpoint = nullptr;
    bool got_endpoint = endpoint_list->Get(i, &endpoint);
    DCHECK(got_endpoint);
    GURL endpoint_url;

    HeaderEndpointOutcome outcome =
        ProcessEndpoint(delegate, cache, now, group, ttl_sec, subdomains,
                        origin, *endpoint, &endpoint_url);
    if (EndpointParsedSuccessfully(outcome))
      new_endpoints->insert(endpoint_url);
    RecordHeaderEndpointOutcome(outcome);
  }

  return HeaderEndpointGroupOutcome::PARSED;
}

}  // namespace

// static
const char ReportingHeaderParser::kHeaderOutcomeHistogram[] =
    "Net.Reporting.HeaderOutcome";

// static
const char ReportingHeaderParser::kHeaderEndpointGroupOutcomeHistogram[] =
    "Net.Reporting.HeaderEndpointGroupOutcome";

// static
const char ReportingHeaderParser::kHeaderEndpointOutcomeHistogram[] =
    "Net.Reporting.HeaderEndpointOutcome";

// static
void ReportingHeaderParser::RecordHeaderDiscardedForNoReportingService() {
  RecordHeaderOutcome(HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE);
}

// static
void ReportingHeaderParser::RecordHeaderDiscardedForInvalidSSLInfo() {
  RecordHeaderOutcome(HeaderOutcome::DISCARDED_INVALID_SSL_INFO);
}

// static
void ReportingHeaderParser::RecordHeaderDiscardedForCertStatusError() {
  RecordHeaderOutcome(HeaderOutcome::DISCARDED_CERT_STATUS_ERROR);
}

// static
void ReportingHeaderParser::RecordHeaderDiscardedForJsonInvalid() {
  RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_INVALID);
}

// static
void ReportingHeaderParser::RecordHeaderDiscardedForJsonTooBig() {
  RecordHeaderOutcome(HeaderOutcome::DISCARDED_JSON_TOO_BIG);
}

// static
void ReportingHeaderParser::ParseHeader(ReportingContext* context,
                                        const GURL& url,
                                        std::unique_ptr<base::Value> value) {
  DCHECK(url.SchemeIsCryptographic());

  const base::ListValue* group_list = nullptr;
  bool is_list = value->GetAsList(&group_list);
  DCHECK(is_list);

  ReportingDelegate* delegate = context->delegate();
  ReportingCache* cache = context->cache();

  url::Origin origin = url::Origin::Create(url);

  std::vector<GURL> old_endpoints;
  cache->GetEndpointsForOrigin(origin, &old_endpoints);

  std::set<GURL> new_endpoints;

  base::TimeTicks now = context->tick_clock()->NowTicks();
  for (size_t i = 0; i < group_list->GetSize(); i++) {
    const base::Value* group = nullptr;
    bool got_group = group_list->Get(i, &group);
    DCHECK(got_group);
    HeaderEndpointGroupOutcome outcome = ProcessEndpointGroup(
        delegate, cache, &new_endpoints, now, origin, *group);
    RecordHeaderEndpointGroupOutcome(outcome);
  }

  // Remove any endpoints that weren't specified in the current header(s).
  for (const GURL& old_endpoint : old_endpoints) {
    if (new_endpoints.count(old_endpoint) == 0u)
      cache->RemoveClientForOriginAndEndpoint(origin, old_endpoint);
  }

  RecordHeaderOutcome(HeaderOutcome::PARSED);
}

}  // namespace net
