// 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/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_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(),
        new 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(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);
    content::BrowserThread::GetTaskRunnerForThread(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.unique());
  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.unique())
    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) {
  // TODO(awdf): Maybe check cached incognito status here to make sure
  // channels are never created in incognito mode.
  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.unique());
  const std::string origin_string = origin.Serialize();
  ContentSetting content_setting =
      content_settings::ValueToContentSetting(rule.value.get());
  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;
}
