// 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 "chrome/browser/subresource_filter/subresource_filter_content_settings_manager.h"

#include <string>

#include "base/bind.h"
#include "base/logging.h"
#include "base/time/default_clock.h"
#include "base/values.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/history/core/browser/history_service.h"
#include "components/keyed_service/core/service_access_type.h"
#include "url/gurl.h"

namespace {

// Key into the website setting dict for the smart UI.
const char kInfobarLastShownTimeKey[] = "InfobarLastShownTime";

bool ShouldUseSmartUI() {
#if defined(OS_ANDROID)
  return true;
#endif
  return false;
}

}  // namespace

constexpr base::TimeDelta
    SubresourceFilterContentSettingsManager::kDelayBeforeShowingInfobarAgain;

SubresourceFilterContentSettingsManager::
    SubresourceFilterContentSettingsManager(Profile* profile)
    : history_observer_(this),
      settings_map_(HostContentSettingsMapFactory::GetForProfile(profile)),
      clock_(std::make_unique<base::DefaultClock>(base::DefaultClock())),
      should_use_smart_ui_(ShouldUseSmartUI()) {
  DCHECK(profile);
  DCHECK(settings_map_);
  if (auto* history_service = HistoryServiceFactory::GetForProfile(
          profile, ServiceAccessType::EXPLICIT_ACCESS)) {
    history_observer_.Add(history_service);
  }
}

SubresourceFilterContentSettingsManager::
    ~SubresourceFilterContentSettingsManager() = default;

ContentSetting SubresourceFilterContentSettingsManager::GetSitePermission(
    const GURL& url) const {
  return settings_map_->GetContentSetting(
      url, GURL(), ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS,
      std::string());
}

void SubresourceFilterContentSettingsManager::WhitelistSite(const GURL& url) {
  settings_map_->SetContentSettingDefaultScope(
      url, GURL(), ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS,
      std::string(), CONTENT_SETTING_ALLOW);
}

void SubresourceFilterContentSettingsManager::OnDidShowUI(const GURL& url) {
  auto dict = std::make_unique<base::DictionaryValue>();
  double now = clock_->Now().ToDoubleT();
  dict->SetDouble(kInfobarLastShownTimeKey, now);
  SetSiteMetadata(url, std::move(dict));
}

bool SubresourceFilterContentSettingsManager::ShouldShowUIForSite(
    const GURL& url) const {
  if (!should_use_smart_ui())
    return true;

  std::unique_ptr<base::DictionaryValue> dict = GetSiteMetadata(url);
  if (!dict)
    return true;

  double last_shown_time_double = 0;
  if (dict->GetDouble(kInfobarLastShownTimeKey, &last_shown_time_double)) {
    base::Time last_shown = base::Time::FromDoubleT(last_shown_time_double);
    if (clock_->Now() - last_shown < kDelayBeforeShowingInfobarAgain)
      return false;
  }
  return true;
}

void SubresourceFilterContentSettingsManager::
    ResetSiteMetadataBasedOnActivation(const GURL& url, bool is_activated) {
  // Do not reset the metadata if it exists already, it could clobber an
  // existing timestamp.
  if (!is_activated) {
    SetSiteMetadata(url, nullptr);
  } else if (!GetSiteMetadata(url)) {
    SetSiteMetadata(url, std::make_unique<base::DictionaryValue>());
  }
}

std::unique_ptr<base::DictionaryValue>
SubresourceFilterContentSettingsManager::GetSiteMetadata(
    const GURL& url) const {
  return base::DictionaryValue::From(settings_map_->GetWebsiteSetting(
      url, GURL(), CONTENT_SETTINGS_TYPE_ADS_DATA, std::string(), nullptr));
}

void SubresourceFilterContentSettingsManager::SetSiteMetadata(
    const GURL& url,
    std::unique_ptr<base::DictionaryValue> dict) {
  settings_map_->SetWebsiteSettingDefaultScope(
      url, GURL(), ContentSettingsType::CONTENT_SETTINGS_TYPE_ADS_DATA,
      std::string(), std::move(dict));
}

// When history URLs are deleted, clear the metadata for the smart UI.
void SubresourceFilterContentSettingsManager::OnURLsDeleted(
    history::HistoryService* history_service,
    const history::DeletionInfo& deletion_info) {
  if (deletion_info.IsAllHistory()) {
    settings_map_->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_ADS_DATA);
    return;
  }

  for (const auto& entry : deletion_info.deleted_urls_origin_map()) {
    const GURL& origin = entry.first;
    int remaining_urls = entry.second.first;
    if (!origin.is_empty() && remaining_urls == 0)
      SetSiteMetadata(origin, nullptr);
  }
}
