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

#include <algorithm>

#include "base/android/build_info.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "base/time/default_clock.h"
#include "base/values.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "components/content_settings/core/browser/content_settings_details.h"
#include "components/content_settings/core/browser/content_settings_pref_provider.h"
#include "components/content_settings/core/browser/content_settings_rule.h"
#include "components/content_settings/core/browser/content_settings_utils.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_pattern.h"
#include "components/content_settings/core/common/content_settings_utils.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "jni/NotificationSettingsBridge_jni.h"
#include "url/gurl.h"
#include "url/origin.h"
#include "url/url_constants.h"

using base::android::AttachCurrentThread;
using base::android::BuildInfo;
using base::android::ConvertUTF8ToJavaString;
using base::android::ScopedJavaLocalRef;

namespace {

class NotificationChannelsBridgeImpl
    : public NotificationChannelsProviderAndroid::NotificationChannelsBridge {
 public:
  NotificationChannelsBridgeImpl() = default;
  ~NotificationChannelsBridgeImpl() override = default;

  bool ShouldUseChannelSettings() override {
    return BuildInfo::GetInstance()->sdk_int() >=
           base::android::SDK_VERSION_OREO;
  }

  NotificationChannel CreateChannel(const std::string& origin,
                                    const base::Time& timestamp,
                                    bool enabled) override {
    JNIEnv* env = AttachCurrentThread();
    ScopedJavaLocalRef<jobject> jchannel =
        Java_NotificationSettingsBridge_createChannel(
            env, ConvertUTF8ToJavaString(env, origin),
            timestamp.ToInternalValue(), enabled);
    return NotificationChannel(
        ConvertJavaStringToUTF8(Java_SiteChannel_getId(env, jchannel)),
        ConvertJavaStringToUTF8(Java_SiteChannel_getOrigin(env, jchannel)),
        base::Time::FromInternalValue(
            Java_SiteChannel_getTimestamp(env, jchannel)),
        static_cast<NotificationChannelStatus>(
            Java_SiteChannel_getStatus(env, jchannel)));
  }

  NotificationChannelStatus GetChannelStatus(
      const std::string& channel_id) override {
    JNIEnv* env = AttachCurrentThread();
    return static_cast<NotificationChannelStatus>(
        Java_NotificationSettingsBridge_getChannelStatus(
            env, ConvertUTF8ToJavaString(env, channel_id)));
  }

  void DeleteChannel(const std::string& origin) override {
    JNIEnv* env = AttachCurrentThread();
    Java_NotificationSettingsBridge_deleteChannel(
        env, ConvertUTF8ToJavaString(env, origin));
  }

  std::vector<NotificationChannel> GetChannels() override {
    JNIEnv* env = AttachCurrentThread();
    ScopedJavaLocalRef<jobjectArray> raw_channels =
        Java_NotificationSettingsBridge_getSiteChannels(env);
    jsize num_channels = env->GetArrayLength(raw_channels.obj());
    std::vector<NotificationChannel> channels;
    for (jsize i = 0; i < num_channels; ++i) {
      ScopedJavaLocalRef<jobject> jchannel(
          env, env->GetObjectArrayElement(raw_channels.obj(), i));
      channels.push_back(NotificationChannel(
          ConvertJavaStringToUTF8(Java_SiteChannel_getId(env, jchannel)),
          ConvertJavaStringToUTF8(Java_SiteChannel_getOrigin(env, jchannel)),
          base::Time::FromInternalValue(
              Java_SiteChannel_getTimestamp(env, jchannel)),
          static_cast<NotificationChannelStatus>(
              Java_SiteChannel_getStatus(env, jchannel))));
    }
    return channels;
  }
};

ContentSetting ChannelStatusToContentSetting(NotificationChannelStatus status) {
  switch (status) {
    case NotificationChannelStatus::ENABLED:
      return CONTENT_SETTING_ALLOW;
    case NotificationChannelStatus::BLOCKED:
      return CONTENT_SETTING_BLOCK;
    case NotificationChannelStatus::UNAVAILABLE:
      NOTREACHED();
  }
  return CONTENT_SETTING_DEFAULT;
}

class ChannelsRuleIterator : public content_settings::RuleIterator {
 public:
  explicit ChannelsRuleIterator(std::vector<NotificationChannel> channels)
      : channels_(std::move(channels)), index_(0) {}

  ~ChannelsRuleIterator() override = default;

  bool HasNext() const override { return index_ < channels_.size(); }

  content_settings::Rule Next() override {
    DCHECK(HasNext());
    DCHECK_NE(channels_[index_].status, NotificationChannelStatus::UNAVAILABLE);
    content_settings::Rule rule = content_settings::Rule(
        ContentSettingsPattern::FromURLNoWildcard(
            GURL(channels_[index_].origin)),
        ContentSettingsPattern::Wildcard(),
        base::Value(ChannelStatusToContentSetting(channels_[index_].status)));
    index_++;
    return rule;
  }

 private:
  std::vector<NotificationChannel> channels_;
  size_t index_;
  DISALLOW_COPY_AND_ASSIGN(ChannelsRuleIterator);
};

// This copies the logic of
// SearchPermissionsService::IsPermissionControlledByDSE, which cannot be
// called from this class as it would introduce a circular dependency between
// the HostContentSettingsMap and the SearchPermissionsService factories.
bool OriginMatchesDefaultSearchEngine(TemplateURLService* template_url_service,
                                      const std::string& origin) {
  if (!template_url_service)
    return false;

  const TemplateURL* default_search_engine =
      template_url_service->GetDefaultSearchProvider();

  if (!default_search_engine)
    return false;

  GURL default_search_engine_url = default_search_engine->GenerateSearchURL(
      template_url_service->search_terms_data());

  return url::IsSameOriginWith(GURL(origin), default_search_engine_url);
}
}  // anonymous namespace

// static
void NotificationChannelsProviderAndroid::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(prefs::kClearedBlockedSiteNotificationChannels,
                                false /* default_value */);
  registry->RegisterBooleanPref(prefs::kMigratedToSiteNotificationChannels,
                                false);
}

NotificationChannel::NotificationChannel(const std::string& id,
                                         const std::string& origin,
                                         const base::Time& timestamp,
                                         NotificationChannelStatus status)
    : id(id), origin(origin), timestamp(timestamp), status(status) {}

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

NotificationChannelsProviderAndroid::NotificationChannelsProviderAndroid()
    : NotificationChannelsProviderAndroid(
          std::make_unique<NotificationChannelsBridgeImpl>(),
          std::make_unique<base::DefaultClock>()) {}

NotificationChannelsProviderAndroid::NotificationChannelsProviderAndroid(
    std::unique_ptr<NotificationChannelsBridge> bridge,
    std::unique_ptr<base::Clock> clock)
    : bridge_(std::move(bridge)),
      platform_supports_channels_(bridge_->ShouldUseChannelSettings()),
      clock_(std::move(clock)),
      initialized_cached_channels_(false),
      weak_factory_(this) {}

NotificationChannelsProviderAndroid::~NotificationChannelsProviderAndroid() =
    default;

void NotificationChannelsProviderAndroid::MigrateToChannelsIfNecessary(
    PrefService* prefs,
    content_settings::ProviderInterface* pref_provider) {
  if (!platform_supports_channels_ ||
      prefs->GetBoolean(prefs::kMigratedToSiteNotificationChannels)) {
    return;
  }
  InitCachedChannels();

  std::vector<content_settings::Rule> rules;

  // Collect the existing rules and create channels for them.
  {
    std::unique_ptr<content_settings::RuleIterator> it(
        pref_provider->GetRuleIterator(CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
                                       std::string(), false /* incognito */));

    while (it && it->HasNext()) {
      content_settings::Rule rule = it->Next();
      rules.push_back(std::move(rule));

      CreateChannelForRule(rule);
    }
  }

  // Remove the existing |rules| from the preference provider.
  for (const auto& rule : rules) {
    pref_provider->SetWebsiteSetting(
        rule.primary_pattern, rule.secondary_pattern,
        CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
        content_settings::ResourceIdentifier(), nullptr);
  }

  prefs->SetBoolean(prefs::kMigratedToSiteNotificationChannels, true);
}

void NotificationChannelsProviderAndroid::ClearBlockedChannelsIfNecessary(
    PrefService* prefs,
    TemplateURLService* template_url_service) {
  if (!platform_supports_channels_ ||
      prefs->GetBoolean(prefs::kClearedBlockedSiteNotificationChannels)) {
    return;
  }

  for (const NotificationChannel& channel : bridge_->GetChannels()) {
    if (channel.status != NotificationChannelStatus::BLOCKED)
      continue;
    if (OriginMatchesDefaultSearchEngine(template_url_service,
                                         channel.origin)) {
      // Do not clear the DSE permission, as it should always be ALLOW or BLOCK.
      continue;
    }
    bridge_->DeleteChannel(channel.id);
  }

  // Reset the cache.
  cached_channels_.clear();
  initialized_cached_channels_ = false;

  prefs->SetBoolean(prefs::kClearedBlockedSiteNotificationChannels, true);
}

std::unique_ptr<content_settings::RuleIterator>
NotificationChannelsProviderAndroid::GetRuleIterator(
    ContentSettingsType content_type,
    const content_settings::ResourceIdentifier& resource_identifier,
    bool incognito) const {
  if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS || incognito ||
      !platform_supports_channels_) {
    return nullptr;
  }
  std::vector<NotificationChannel> channels = UpdateCachedChannels();
  return channels.empty()
             ? nullptr
             : std::make_unique<ChannelsRuleIterator>(std::move(channels));
}

std::vector<NotificationChannel>
NotificationChannelsProviderAndroid::UpdateCachedChannels() const {
  std::vector<NotificationChannel> channels = bridge_->GetChannels();
  std::map<std::string, NotificationChannel> updated_channels_map;
  for (const auto& channel : channels)
    updated_channels_map.emplace(channel.origin, channel);
  if (updated_channels_map != cached_channels_) {
    // This const_cast is not ideal but tolerated because it doesn't change the
    // underlying state of NotificationChannelsProviderAndroid, and allows us to
    // notify observers as soon as we detect changes to channels.
    auto* provider = const_cast<NotificationChannelsProviderAndroid*>(this);
    base::CreateSingleThreadTaskRunnerWithTraits({content::BrowserThread::UI})
        ->PostTask(FROM_HERE,
                   base::BindOnce(
                       &NotificationChannelsProviderAndroid::NotifyObservers,
                       provider->weak_factory_.GetWeakPtr(),
                       ContentSettingsPattern(), ContentSettingsPattern(),
                       CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string()));
    provider->cached_channels_ = std::move(updated_channels_map);
    provider->initialized_cached_channels_ = true;
  }
  return channels;
}

bool NotificationChannelsProviderAndroid::SetWebsiteSetting(
    const ContentSettingsPattern& primary_pattern,
    const ContentSettingsPattern& secondary_pattern,
    ContentSettingsType content_type,
    const content_settings::ResourceIdentifier& resource_identifier,
    base::Value* value) {
  if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
      !platform_supports_channels_) {
    return false;
  }
  // This provider only handles settings for specific origins.
  if (primary_pattern == ContentSettingsPattern::Wildcard() &&
      secondary_pattern == ContentSettingsPattern::Wildcard() &&
      resource_identifier.empty()) {
    return false;
  }

  InitCachedChannels();

  url::Origin origin = url::Origin::Create(GURL(primary_pattern.ToString()));
  DCHECK(!origin.opaque());
  const std::string origin_string = origin.Serialize();

  ContentSetting setting = content_settings::ValueToContentSetting(value);
  switch (setting) {
    case CONTENT_SETTING_ALLOW:
      CreateChannelIfRequired(origin_string,
                              NotificationChannelStatus::ENABLED);
      break;
    case CONTENT_SETTING_BLOCK:
      CreateChannelIfRequired(origin_string,
                              NotificationChannelStatus::BLOCKED);
      break;
    case CONTENT_SETTING_DEFAULT: {
      auto channel_to_delete = cached_channels_.find(origin_string);
      if (channel_to_delete != cached_channels_.end()) {
        bridge_->DeleteChannel(channel_to_delete->second.id);
        cached_channels_.erase(channel_to_delete);
      }
      return false;
    }
    default:
      // We rely on notification settings being one of ALLOW/BLOCK/DEFAULT.
      NOTREACHED();
      break;
  }
  return true;
}

void NotificationChannelsProviderAndroid::ClearAllContentSettingsRules(
    ContentSettingsType content_type) {
  if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
      !platform_supports_channels_) {
    return;
  }
  std::vector<NotificationChannel> channels = bridge_->GetChannels();
  for (auto channel : channels)
    bridge_->DeleteChannel(channel.id);
  cached_channels_.clear();

  if (channels.size() > 0) {
    NotifyObservers(ContentSettingsPattern(), ContentSettingsPattern(),
                    content_type, std::string());
  }
}

void NotificationChannelsProviderAndroid::ShutdownOnUIThread() {
  RemoveAllObservers();
}

base::Time NotificationChannelsProviderAndroid::GetWebsiteSettingLastModified(
    const ContentSettingsPattern& primary_pattern,
    const ContentSettingsPattern& secondary_pattern,
    ContentSettingsType content_type,
    const content_settings::ResourceIdentifier& resource_identifier) {
  if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS ||
      !platform_supports_channels_) {
    return base::Time();
  }
  url::Origin origin = url::Origin::Create(GURL(primary_pattern.ToString()));
  if (origin.opaque())
    return base::Time();
  const std::string origin_string = origin.Serialize();

  InitCachedChannels();
  auto channel_entry = cached_channels_.find(origin_string);
  if (channel_entry == cached_channels_.end())
    return base::Time();

  return channel_entry->second.timestamp;
}

// InitCachedChannels() must be called prior to calling this method.
void NotificationChannelsProviderAndroid::CreateChannelIfRequired(
    const std::string& origin_string,
    NotificationChannelStatus new_channel_status) {
  auto channel_entry = cached_channels_.find(origin_string);
  if (channel_entry == cached_channels_.end()) {
    base::Time timestamp = clock_->Now();

    NotificationChannel channel = bridge_->CreateChannel(
        origin_string, timestamp,
        new_channel_status == NotificationChannelStatus::ENABLED);
    cached_channels_.emplace(origin_string, std::move(channel));

    NotifyObservers(ContentSettingsPattern(), ContentSettingsPattern(),
                    CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string());
  } else {
    auto old_channel_status =
        bridge_->GetChannelStatus(channel_entry->second.id);
    DCHECK_EQ(old_channel_status, new_channel_status);
  }
}

// InitCachedChannels() must be called prior to calling this method.
void NotificationChannelsProviderAndroid::CreateChannelForRule(
    const content_settings::Rule& rule) {
  url::Origin origin =
      url::Origin::Create(GURL(rule.primary_pattern.ToString()));
  DCHECK(!origin.opaque());
  const std::string origin_string = origin.Serialize();
  ContentSetting content_setting =
      content_settings::ValueToContentSetting(&rule.value);
  switch (content_setting) {
    case CONTENT_SETTING_ALLOW:
      CreateChannelIfRequired(origin_string,
                              NotificationChannelStatus::ENABLED);
      break;
    case CONTENT_SETTING_BLOCK:
      CreateChannelIfRequired(origin_string,
                              NotificationChannelStatus::BLOCKED);
      break;
    default:
      // We assume notification preferences are either ALLOW/BLOCK.
      NOTREACHED();
      break;
  }
}

// This method must be called prior to accessing |cached_channels_|.
void NotificationChannelsProviderAndroid::InitCachedChannels() {
  if (initialized_cached_channels_)
    return;
  DCHECK_EQ(cached_channels_.size(), 0u);
  std::vector<NotificationChannel> channels = bridge_->GetChannels();
  for (auto channel : channels)
    cached_channels_.emplace(channel.origin, std::move(channel));
  initialized_cached_channels_ = true;
}
