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

#include "chrome/browser/extensions/preference/preference_helpers.h"

#include <memory>
#include <utility>

#include "base/json/json_writer.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "components/prefs/pref_service.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_prefs_helper.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_util.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest_handlers/incognito_info.h"
#include "extensions/common/permissions/permissions_data.h"

namespace extensions {
namespace preference_helpers {

namespace {

constexpr char kNotControllable[] = "not_controllable";
constexpr char kControlledByOtherExtensions[] =
    "controlled_by_other_extensions";
constexpr char kControllableByThisExtension[] =
    "controllable_by_this_extension";
constexpr char kControlledByThisExtension[] = "controlled_by_this_extension";

constexpr char kLevelOfControlKey[] = "levelOfControl";

}  // namespace

using LevelOfControlGetter =
    base::RepeatingCallback<const char*(Profile*,
                                        const ExtensionId& extension_id,
                                        const std::string& browser_pref,
                                        bool incognito)>;

PrefService* GetProfilePrefService(Profile* profile, bool incognito) {
  if (incognito) {
    if (profile->HasPrimaryOTRProfile()) {
      return profile->GetPrimaryOTRProfile(/*create_if_needed=*/false)
          ->GetPrefs();
    }
    return profile->GetReadOnlyOffTheRecordPrefs();
  }

  return profile->GetPrefs();
}

const char* GetLevelOfControl(Profile* profile,
                              const ExtensionId& extension_id,
                              const std::string& browser_pref,
                              bool incognito) {
  PrefService* prefs = GetProfilePrefService(profile, incognito);
  bool from_incognito = false;
  bool* from_incognito_ptr = incognito ? &from_incognito : nullptr;
  const PrefService::Preference* pref = prefs->FindPreference(browser_pref);
  if (!pref->IsExtensionModifiable())
    return kNotControllable;

  if (ExtensionPrefsHelper::Get(profile)->DoesExtensionControlPref(
          extension_id, browser_pref, from_incognito_ptr)) {
    return kControlledByThisExtension;
  }

  if (ExtensionPrefsHelper::Get(profile)->CanExtensionControlPref(
          extension_id, browser_pref, incognito)) {
    return kControllableByThisExtension;
  }

  return kControlledByOtherExtensions;
}

void DispatchEventToExtensionsImpl(Profile* profile,
                                   events::HistogramValue histogram_value,
                                   const std::string& event_name,
                                   base::Value::List args,
                                   mojom::APIPermissionID permission,
                                   bool incognito,
                                   const std::string& browser_pref,
                                   const LevelOfControlGetter level_getter) {
  EventRouter* router = EventRouter::Get(profile);
  if (!router || !router->HasEventListener(event_name))
    return;

  for (const scoped_refptr<const extensions::Extension>& extension :
       ExtensionRegistry::Get(profile)->enabled_extensions()) {
    // TODO(bauerb): Only iterate over registered event listeners.
    if (router->ExtensionHasEventListener(extension->id(), event_name) &&
        extension->permissions_data()->HasAPIPermission(permission) &&
        (!incognito || util::IsIncognitoEnabled(extension->id(), profile))) {
      // Inject level of control key-value.
      DCHECK(!args.empty());
      DCHECK(args[0].is_dict());

      std::string level_of_control =
          level_getter.Run(profile, extension->id(), browser_pref, incognito);

      args[0].GetDict().Set(kLevelOfControlKey, level_of_control);

      // If the extension is in incognito split mode,
      // a) incognito pref changes are visible only to the incognito tabs
      // b) regular pref changes are visible only to the incognito tabs if the
      //    incognito pref has not already been set
      Profile* restrict_to_profile = nullptr;
      if (IncognitoInfo::IsSplitMode(extension.get())) {
        if (incognito) {  // Handle case a).
          // If off the record profile does not exist, there should be no
          // extensions running in incognito at this time, and consequentially
          // no need to dispatch an event restricted to an incognito extension.
          // Furthermore, avoid calling GetPrimaryOTRProfile() if the profile
          // does not exist. Unnecessarily creating off the record profile is
          // undesirable, and can lead to a crash if incognito is disallowed for
          // the current profile (see https://crbug.com/796814).
          if (!profile->HasPrimaryOTRProfile())
            continue;
          restrict_to_profile =
              profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
        } else {  // Handle case b).
          bool controlled_from_incognito = false;
          bool controlled_by_extension =
              ExtensionPrefsHelper::Get(profile)->DoesExtensionControlPref(
                  extension->id(), browser_pref, &controlled_from_incognito);
          if (controlled_by_extension && controlled_from_incognito)
            restrict_to_profile = profile;
        }
      }

      base::Value::List args_copy = args.Clone();
      auto event =
          std::make_unique<Event>(histogram_value, event_name,
                                  std::move(args_copy), restrict_to_profile);
      router->DispatchEventToExtension(extension->id(), std::move(event));
    }
  }
}

void DispatchEventToExtensions(Profile* profile,
                               events::HistogramValue histogram_value,
                               const std::string& event_name,
                               base::Value::List args,
                               mojom::APIPermissionID permission,
                               bool incognito,
                               const std::string& browser_pref) {
  DispatchEventToExtensionsImpl(
      profile, histogram_value, event_name, std::move(args), permission,
      incognito, browser_pref, base::BindRepeating(GetLevelOfControl));
}
}  // namespace preference_helpers
}  // namespace extensions
