// 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/ui/extensions/extension_enable_flow.h"

#include <memory>

#include "base/check.h"
#include "base/functional/bind.h"
#include "base/notreached.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/supervised_user/supervised_user_browser_utils.h"
#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
#include "extensions/browser/api/management/management_api.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extension_registrar.h"
#include "extensions/browser/extension_system.h"
#include "ui/gfx/native_window_types.h"

#if !BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ui/profiles/profile_picker.h"
#endif  // !BUILDFLAG(IS_CHROMEOS)

using extensions::Extension;

ExtensionEnableFlow::ExtensionEnableFlow(Profile* profile,
                                         const std::string& extension_id,
                                         ExtensionEnableFlowDelegate* delegate)
    : profile_(profile), extension_id_(extension_id), delegate_(delegate) {}

ExtensionEnableFlow::~ExtensionEnableFlow() = default;

void ExtensionEnableFlow::StartForWebContents(
    content::WebContents* parent_contents) {
  parent_contents_ = parent_contents;
  parent_window_ = gfx::NativeWindow();
  Run();
}

void ExtensionEnableFlow::StartForNativeWindow(
    gfx::NativeWindow parent_window) {
  parent_contents_ = nullptr;
  parent_window_ = parent_window;
  Run();
}

void ExtensionEnableFlow::Start() {
  Run();
}

void ExtensionEnableFlow::Run() {
  extensions::ExtensionRegistry* registry =
      extensions::ExtensionRegistry::Get(profile_);
  const Extension* extension =
      registry->disabled_extensions().GetByID(extension_id_);
  if (!extension) {
    extension = registry->terminated_extensions().GetByID(extension_id_);
    // It's possible (though unlikely) the app could have been uninstalled since
    // the user clicked on it.
    if (!extension) {
      return;
    }
    // If the app was terminated, reload it first.
    extensions::ExtensionRegistrar::Get(profile_)->ReloadExtension(
        extension_id_);

    // ReloadExtension reallocates the Extension object.
    extension = registry->disabled_extensions().GetByID(extension_id_);

    // |extension| could be nullptr for asynchronous load, such as the case of
    // an unpacked extension. Wait for the load to continue the flow.
    if (!extension) {
      StartObserving();
      return;
    }
  }

  CheckPermissionAndMaybePromptUser();
}

void ExtensionEnableFlow::CheckPermissionAndMaybePromptUser() {
  auto* system = extensions::ExtensionSystem::Get(profile_);
  auto* registrar = extensions::ExtensionRegistrar::Get(profile_);
  auto* registry = extensions::ExtensionRegistry::Get(profile_);
  const Extension* extension =
      registry->disabled_extensions().GetByID(extension_id_);

  extensions::SupervisedUserExtensionsDelegate*
      supervised_user_extensions_delegate =
          extensions::ManagementAPI::GetFactoryInstance()
              ->Get(profile_)
              ->GetSupervisedUserExtensionsDelegate();
  DCHECK(supervised_user_extensions_delegate);
  if (supervised_user::AreExtensionsPermissionsEnabled(profile_) && extension &&

      // Only ask for parent approval if the extension still requires approval.
      !supervised_user_extensions_delegate->IsExtensionAllowedByParent(
          *extension)) {
    // Either ask for parent permission or notify the child that their parent
    // has disabled this action.
    auto extension_approval_callback =
        base::BindOnce(&ExtensionEnableFlow::OnExtensionApprovalDone,
                       weak_ptr_factory_.GetWeakPtr());
    supervised_user_extensions_delegate->RequestToEnableExtensionOrShowError(
        *extension, parent_contents_, std::move(extension_approval_callback));
    return;
  }

  bool abort =
      !extension ||
      // The extension might be force-disabled by policy.
      system->management_policy()->MustRemainDisabled(extension, nullptr);
  if (abort) {
    delegate_->ExtensionEnableFlowAborted(
        /*user_initiated=*/false);  // |delegate_| may delete us.
    return;
  }

  if (profiles::IsProfileLocked(profile_->GetPath())) {
#if !BUILDFLAG(IS_CHROMEOS)
    ProfilePicker::Show(ProfilePicker::Params::FromEntryPoint(
        ProfilePicker::EntryPoint::kProfileLocked));

#endif  // !BUILDFLAG(IS_CHROMEOS)
    return;
  }

  extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
  if (!prefs->DidExtensionEscalatePermissions(extension_id_)) {
    // Enable the extension immediately if its privileges weren't escalated.
    // This is a no-op if the extension was previously terminated.
    registrar->EnableExtension(extension_id_);

    DCHECK(registrar->IsExtensionEnabled(extension_id_));
    delegate_->ExtensionEnableFlowFinished();  // |delegate_| may delete us.
    return;
  }

  CreatePrompt();
  ExtensionInstallPrompt::PromptType type =
      ExtensionInstallPrompt::GetReEnablePromptTypeForExtension(profile_,
                                                                extension);
  prompt_->ShowDialog(base::BindOnce(&ExtensionEnableFlow::InstallPromptDone,
                                     weak_ptr_factory_.GetWeakPtr()),
                      extension, nullptr,
                      std::make_unique<ExtensionInstallPrompt::Prompt>(type),
                      ExtensionInstallPrompt::GetDefaultShowDialogCallback());
}

void ExtensionEnableFlow::CreatePrompt() {
  prompt_.reset(parent_contents_ ? new ExtensionInstallPrompt(parent_contents_)
                                 : new ExtensionInstallPrompt(
                                       profile_, gfx::NativeWindow()));
}

void ExtensionEnableFlow::OnExtensionApprovalDone(
    extensions::SupervisedUserExtensionsDelegate::ExtensionApprovalResult
        result) {
  switch (result) {
    case extensions::SupervisedUserExtensionsDelegate::ExtensionApprovalResult::
        kApproved:
      EnableExtension();
      break;
    case extensions::SupervisedUserExtensionsDelegate::ExtensionApprovalResult::
        kCanceled:
      delegate_->ExtensionEnableFlowAborted(
          /*user_initiated=*/true);  // |delegate_| may delete us.
      break;
    case extensions::SupervisedUserExtensionsDelegate::ExtensionApprovalResult::
        kFailed:
    case extensions::SupervisedUserExtensionsDelegate::ExtensionApprovalResult::
        kBlocked:
      delegate_->ExtensionEnableFlowAborted(
          /*user_initiated=*/false);  // |delegate_| may delete us.
      break;
  }
}

void ExtensionEnableFlow::StartObserving() {
  extension_registry_observation_.Observe(
      extensions::ExtensionRegistry::Get(profile_));
  load_error_observation_.Observe(extensions::LoadErrorReporter::GetInstance());
}

void ExtensionEnableFlow::StopObserving() {
  extension_registry_observation_.Reset();
  load_error_observation_.Reset();
}

void ExtensionEnableFlow::OnLoadFailure(
    content::BrowserContext* browser_context,
    const base::FilePath& file_path,
    const std::string& error) {
  StopObserving();
  delegate_->ExtensionEnableFlowAborted(
      /*user_initiated=*/false);  // |delegate_| may delete us.
}

void ExtensionEnableFlow::OnExtensionLoaded(
    content::BrowserContext* browser_context,
    const Extension* extension) {
  if (extension->id() == extension_id_) {
    StopObserving();
    CheckPermissionAndMaybePromptUser();
  }
}

void ExtensionEnableFlow::OnExtensionUninstalled(
    content::BrowserContext* browser_context,
    const Extension* extension,
    extensions::UninstallReason reason) {
  if (extension->id() == extension_id_) {
    StopObserving();
    delegate_->ExtensionEnableFlowAborted(
        /*user_initiated=*/false);  // |delegate_| may delete us.
  }
}

void ExtensionEnableFlow::EnableExtension() {
  extensions::ExtensionRegistry* registry =
      extensions::ExtensionRegistry::Get(profile_);
  // The extension can be uninstalled in another window while the UI was
  // showing. Treat it as a cancellation and notify |delegate_|.
  const Extension* extension =
      registry->disabled_extensions().GetByID(extension_id_);
  if (!extension) {
    delegate_->ExtensionEnableFlowAborted(
        /*user_initiated=*/true);  // |delegate_| may delete us.
    return;
  }
  if (supervised_user::AreExtensionsPermissionsEnabled(profile_)) {
    // We need to add parent approval first.
    extensions::SupervisedUserExtensionsDelegate*
        supervised_user_extensions_delegate =
            extensions::ManagementAPI::GetFactoryInstance()
                ->Get(profile_)
                ->GetSupervisedUserExtensionsDelegate();
    CHECK(supervised_user_extensions_delegate);
    supervised_user_extensions_delegate->AddExtensionApproval(*extension);
    supervised_user_extensions_delegate->MaybeRecordPermissionsIncreaseMetrics(
        *extension);
    supervised_user_extensions_delegate->RecordExtensionEnablementUmaMetrics(
        /*enabled=*/true);
  }
  auto* registrar = extensions::ExtensionRegistrar::Get(profile_);
  registrar->GrantPermissionsAndEnableExtension(*extension);

  DCHECK(registrar->IsExtensionEnabled(extension_id_));
  delegate_->ExtensionEnableFlowFinished();  // |delegate_| may delete us.
}

void ExtensionEnableFlow::InstallPromptDone(
    ExtensionInstallPrompt::DoneCallbackPayload payload) {
  switch (payload.result) {
    case ExtensionInstallPrompt::Result::ACCEPTED:
      EnableExtension();
      break;
    case ExtensionInstallPrompt::Result::ACCEPTED_WITH_WITHHELD_PERMISSIONS:
      // This dialog doesn't support the "withhold permissions" checkbox.
      NOTREACHED();
    case ExtensionInstallPrompt::Result::USER_CANCELED:
    case ExtensionInstallPrompt::Result::ABORTED:
      delegate_->ExtensionEnableFlowAborted(/*user_initiated=*/
                                            payload.result ==
                                            ExtensionInstallPrompt::Result::
                                                USER_CANCELED);
      // `delegate_` may delete us.
      break;
  }
}
