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

#include "extensions/browser/api/power/power_api.h"

#include "base/functional/bind.h"
#include "base/lazy_instance.h"
#include "content/public/browser/device_service.h"
#include "extensions/browser/api/power/activity_reporter_delegate.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/api/power.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_id.h"
#include "services/device/public/mojom/wake_lock_provider.mojom.h"

namespace extensions {

namespace {

const char kWakeLockDescription[] = "extension";

device::mojom::WakeLockType LevelToWakeLockType(api::power::Level level) {
  switch (level) {
    case api::power::Level::kSystem:
      return device::mojom::WakeLockType::kPreventAppSuspension;
    case api::power::Level::kDisplay:  // fallthrough
    case api::power::Level::kNone:
      return device::mojom::WakeLockType::kPreventDisplaySleep;
  }
  NOTREACHED() << "Unhandled power level: " << api::power::ToString(level);
}

base::LazyInstance<BrowserContextKeyedAPIFactory<PowerAPI>>::DestructorAtExit
    g_factory = LAZY_INSTANCE_INITIALIZER;

}  // namespace

ExtensionFunction::ResponseAction PowerRequestKeepAwakeFunction::Run() {
  std::optional<api::power::RequestKeepAwake::Params> params =
      api::power::RequestKeepAwake::Params::Create(args());
  EXTENSION_FUNCTION_VALIDATE(params);
  PowerAPI::Get(browser_context())->AddRequest(extension_id(), params->level);
  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction PowerReleaseKeepAwakeFunction::Run() {
  PowerAPI::Get(browser_context())->RemoveRequest(extension_id());
  return RespondNow(NoArguments());
}

#if BUILDFLAG(IS_CHROMEOS)
ExtensionFunction::ResponseAction PowerReportActivityFunction::Run() {
  std::optional<std::string> error =
      extensions::ActivityReporterDelegate::GetDelegate()->ReportActivity();
  if (error.has_value()) {
    return RespondNow(Error(error.value()));
  }
  return RespondNow(NoArguments());
}
#endif  // BUILDFLAG(IS_CHROMEOS)

// static
PowerAPI* PowerAPI::Get(content::BrowserContext* context) {
  return BrowserContextKeyedAPIFactory<PowerAPI>::Get(context);
}

// static
BrowserContextKeyedAPIFactory<PowerAPI>* PowerAPI::GetFactoryInstance() {
  return g_factory.Pointer();
}

void PowerAPI::AddRequest(const ExtensionId& extension_id,
                          api::power::Level level) {
  extension_levels_[extension_id] = level;
  UpdateWakeLock();
}

void PowerAPI::RemoveRequest(const ExtensionId& extension_id) {
  extension_levels_.erase(extension_id);
  UpdateWakeLock();
}

void PowerAPI::SetWakeLockFunctionsForTesting(
    ActivateWakeLockFunction activate_function,
    CancelWakeLockFunction cancel_function) {
  activate_wake_lock_function_ =
      !activate_function.is_null()
          ? std::move(activate_function)
          : base::BindRepeating(&PowerAPI::ActivateWakeLock,
                                base::Unretained(this));
  cancel_wake_lock_function_ =
      !cancel_function.is_null()
          ? std::move(cancel_function)
          : base::BindRepeating(&PowerAPI::CancelWakeLock,
                                base::Unretained(this));
}

void PowerAPI::OnExtensionUnloaded(content::BrowserContext* browser_context,
                                   const Extension* extension,
                                   UnloadedExtensionReason reason) {
  RemoveRequest(extension->id());
  UpdateWakeLock();
}

PowerAPI::PowerAPI(content::BrowserContext* context)
    : browser_context_(context),
      activate_wake_lock_function_(
          base::BindRepeating(&PowerAPI::ActivateWakeLock,
                              base::Unretained(this))),
      cancel_wake_lock_function_(base::BindRepeating(&PowerAPI::CancelWakeLock,
                                                     base::Unretained(this))),
      is_wake_lock_active_(false),
      current_level_(api::power::Level::kSystem) {
  ExtensionRegistry::Get(browser_context_)->AddObserver(this);
}

PowerAPI::~PowerAPI() = default;

void PowerAPI::UpdateWakeLock() {
  if (extension_levels_.empty()) {
    cancel_wake_lock_function_.Run();
    return;
  }

  api::power::Level new_level = api::power::Level::kSystem;
  for (ExtensionLevelMap::const_iterator it = extension_levels_.begin();
       it != extension_levels_.end(); ++it) {
    if (it->second == api::power::Level::kDisplay) {
      new_level = it->second;
    }
  }

  if (!is_wake_lock_active_ || new_level != current_level_) {
    device::mojom::WakeLockType type = LevelToWakeLockType(new_level);
    activate_wake_lock_function_.Run(type);
    current_level_ = new_level;
  }
}

void PowerAPI::Shutdown() {
  // Unregister here rather than in the d'tor; otherwise this call will recreate
  // the already-deleted ExtensionRegistry.
  ExtensionRegistry::Get(browser_context_)->RemoveObserver(this);
  cancel_wake_lock_function_.Run();
}

void PowerAPI::ActivateWakeLock(device::mojom::WakeLockType type) {
  GetWakeLock()->ChangeType(type, base::DoNothing());
  if (!is_wake_lock_active_) {
    GetWakeLock()->RequestWakeLock();
    is_wake_lock_active_ = true;
  }
}

void PowerAPI::CancelWakeLock() {
  if (is_wake_lock_active_) {
    GetWakeLock()->CancelWakeLock();
    is_wake_lock_active_ = false;
  }
}

device::mojom::WakeLock* PowerAPI::GetWakeLock() {
  // Here is a lazy binding, and will not reconnect after connection error.
  if (wake_lock_) {
    return wake_lock_.get();
  }

  mojo::Remote<device::mojom::WakeLockProvider> wake_lock_provider;
  content::GetDeviceService().BindWakeLockProvider(
      wake_lock_provider.BindNewPipeAndPassReceiver());
  wake_lock_provider->GetWakeLockWithoutContext(
      LevelToWakeLockType(current_level_),
      device::mojom::WakeLockReason::kOther, kWakeLockDescription,
      wake_lock_.BindNewPipeAndPassReceiver());
  return wake_lock_.get();
}

}  // namespace extensions
