// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/cookies/cookie_deletion_info.h"

#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_options.h"

namespace net {

namespace {

// Return true if the eTLD+1 of the cookies domain matches any of the strings
// in |match_domains|, false otherwise.
bool DomainMatchesDomains(const net::CanonicalCookie& cookie,
                          const std::set<std::string>& match_domains) {
  if (match_domains.empty())
    return false;

  // If domain is an IP address it returns an empty string.
  std::string effective_domain(
      net::registry_controlled_domains::GetDomainAndRegistry(
          // GetDomainAndRegistry() is insensitive to leading dots, i.e.
          // to host/domain cookie distinctions.
          cookie.Domain(),
          net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES));
  // If the cookie's domain is is not parsed as belonging to a registry
  // (e.g. for IP addresses or internal hostnames) an empty string will be
  // returned.  In this case, use the domain in the cookie.
  if (effective_domain.empty())
    effective_domain = cookie.DomainWithoutDot();

  return match_domains.count(effective_domain) != 0;
}

}  // anonymous namespace

CookieDeletionInfo::TimeRange::TimeRange() = default;

CookieDeletionInfo::TimeRange::TimeRange(const TimeRange& other) = default;

CookieDeletionInfo::TimeRange::TimeRange(base::Time start, base::Time end)
    : start_(start), end_(end) {
  if (!start.is_null() && !end.is_null())
    DCHECK_GE(end, start);
}

CookieDeletionInfo::TimeRange& CookieDeletionInfo::TimeRange::operator=(
    const TimeRange& rhs) = default;

bool CookieDeletionInfo::TimeRange::Contains(base::Time time) const {
  DCHECK(!time.is_null());

  if (!start_.is_null() && start_ == end_)
    return time == start_;
  return (start_.is_null() || start_ <= time) &&
         (end_.is_null() || time < end_);
}

void CookieDeletionInfo::TimeRange::SetStart(base::Time value) {
  start_ = value;
}

void CookieDeletionInfo::TimeRange::SetEnd(base::Time value) {
  end_ = value;
}

CookieDeletionInfo::CookieDeletionInfo()
    : CookieDeletionInfo(base::Time(), base::Time()) {}

CookieDeletionInfo::CookieDeletionInfo(base::Time start_time,
                                       base::Time end_time)
    : creation_range(start_time, end_time) {}

CookieDeletionInfo::CookieDeletionInfo(CookieDeletionInfo&& other) = default;

CookieDeletionInfo::CookieDeletionInfo(const CookieDeletionInfo& other) =
    default;

CookieDeletionInfo::~CookieDeletionInfo() = default;

CookieDeletionInfo& CookieDeletionInfo::operator=(CookieDeletionInfo&& rhs) =
    default;

CookieDeletionInfo& CookieDeletionInfo::operator=(
    const CookieDeletionInfo& rhs) = default;

bool CookieDeletionInfo::Matches(const CanonicalCookie& cookie,
                                 const CookieAccessParams& params) const {
  if (session_control != SessionControl::IGNORE_CONTROL &&
      (cookie.IsPersistent() !=
       (session_control == SessionControl::PERSISTENT_COOKIES))) {
    return false;
  }

  if (!creation_range.Contains(cookie.CreationDate()))
    return false;

  if (host.has_value() &&
      !(cookie.IsHostCookie() && cookie.IsDomainMatch(host.value()))) {
    return false;
  }

  if (name.has_value() && cookie.Name() != name)
    return false;

  if (value_for_testing.has_value() &&
      value_for_testing.value() != cookie.Value()) {
    return false;
  }

  // |CookieOptions::MakeAllInclusive()| options will make sure that all
  // cookies associated with the URL are deleted.
  if (url.has_value() &&
      !cookie
           .IncludeForRequestURL(url.value(), CookieOptions::MakeAllInclusive(),
                                 params)
           .status.IsInclude()) {
    return false;
  }

  if (domains_and_ips_to_delete.has_value() &&
      !DomainMatchesDomains(cookie, *domains_and_ips_to_delete)) {
    return false;
  }

  if (domains_and_ips_to_ignore.has_value() &&
      DomainMatchesDomains(cookie, *domains_and_ips_to_ignore)) {
    return false;
  }

  if (cookie.IsPartitioned() &&
      !cookie_partition_key_collection.Contains(*cookie.PartitionKey())) {
    return false;
  }

  if (partitioned_state_only && !cookie.IsPartitioned()) {
    return false;
  }

  return true;
}

}  // namespace net
