// Copyright 2015 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 "components/domain_reliability/context_manager.h"

#include <utility>

#include "base/metrics/histogram_macros.h"

namespace domain_reliability {

DomainReliabilityContextManager::DomainReliabilityContextManager(
    DomainReliabilityContext::Factory* context_factory)
    : context_factory_(context_factory) {
}

DomainReliabilityContextManager::~DomainReliabilityContextManager() {
  RemoveContexts(
      base::Callback<bool(const GURL&)>() /* no filter - delete everything */);
}

void DomainReliabilityContextManager::RouteBeacon(
    std::unique_ptr<DomainReliabilityBeacon> beacon) {
  DomainReliabilityContext* context = GetContextForHost(beacon->url.host());
  if (!context)
    return;

  context->OnBeacon(std::move(beacon));
}

void DomainReliabilityContextManager::SetConfig(
    const GURL& origin,
    std::unique_ptr<DomainReliabilityConfig> config,
    base::TimeDelta max_age) {
  std::string key = origin.host();

  if (!contexts_.count(key) && !removed_contexts_.count(key)) {
    DLOG(WARNING) << "Ignoring NEL header for unknown origin " << origin.spec()
                  << ".";
    return;
  }

  if (contexts_.count(key)) {
    // Currently, there is no easy way to change the config of a context, so
    // updating the config requires recreating the context, which loses
    // pending beacons and collector backoff state. Therefore, don't do so
    // needlessly; make sure the config has actually changed before recreating
    // the context.
    bool config_same = contexts_[key]->config().Equals(*config);
    if (!config_same) {
      DVLOG(1) << "Ignoring unchanged NEL header for existing origin "
               << origin.spec() << ".";
      return;
    }
    // TODO(juliatuttle): Make Context accept Config changes.
  }

  DVLOG(1) << "Adding/replacing context for existing origin " << origin.spec()
           << ".";
  removed_contexts_.erase(key);
  config->origin = origin;
  AddContextForConfig(std::move(config));
}

void DomainReliabilityContextManager::ClearConfig(const GURL& origin) {
  std::string key = origin.host();

  if (contexts_.count(key)) {
    DVLOG(1) << "Removing context for existing origin " << origin.spec() << ".";
    contexts_.erase(key);
    removed_contexts_.insert(key);
  }
}

void DomainReliabilityContextManager::ClearBeacons(
    const base::Callback<bool(const GURL&)>& origin_filter) {
  for (auto& context_entry : contexts_) {
    if (origin_filter.is_null() ||
        origin_filter.Run(context_entry.second->config().origin)) {
      context_entry.second->ClearBeacons();
    }
  }
}

DomainReliabilityContext* DomainReliabilityContextManager::AddContextForConfig(
    std::unique_ptr<const DomainReliabilityConfig> config) {
  std::string key = config->origin.host();
  // TODO(juliatuttle): Convert this to actual origin.

  std::unique_ptr<DomainReliabilityContext> context =
      context_factory_->CreateContextForConfig(std::move(config));
  DomainReliabilityContext** entry = &contexts_[key];
  if (*entry)
    delete *entry;

  *entry = context.release();
  return *entry;
}

void DomainReliabilityContextManager::RemoveContexts(
    const base::Callback<bool(const GURL&)>& origin_filter) {
  for (auto it = contexts_.begin(); it != contexts_.end();) {
    if (!origin_filter.is_null() &&
        !origin_filter.Run(it->second->config().origin)) {
      ++it;
      continue;
    }

    delete it->second;
    it = contexts_.erase(it);
  }
}

std::unique_ptr<base::Value> DomainReliabilityContextManager::GetWebUIData()
    const {
  std::unique_ptr<base::ListValue> contexts_value(new base::ListValue());
  for (const auto& context_entry : contexts_)
    contexts_value->Append(context_entry.second->GetWebUIData());
  return std::move(contexts_value);
}

DomainReliabilityContext* DomainReliabilityContextManager::GetContextForHost(
    const std::string& host) {
  ContextMap::const_iterator context_it;

  context_it = contexts_.find(host);
  if (context_it != contexts_.end())
    return context_it->second;

  size_t dot_pos = host.find('.');
  if (dot_pos == std::string::npos)
    return nullptr;

  // TODO(juliatuttle): Make sure parent is not in PSL before using.

  std::string parent_host = host.substr(dot_pos + 1);
  context_it = contexts_.find(parent_host);
  if (context_it != contexts_.end()
      && context_it->second->config().include_subdomains) {
    return context_it->second;
  }

  return nullptr;
}

}  // namespace domain_reliability
