// Copyright 2013 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/api/tabs/windows_util.h"

#include <string>
#include <vector>

#include "base/strings/string_number_conversions.h"
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/extensions/window_controller.h"
#include "chrome/browser/extensions/window_controller_list.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/incognito_allowed_url.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "extensions/browser/extension_function.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/constants.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "url/gurl.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace windows_util {

bool GetControllerFromWindowID(ExtensionFunction* function,
                               int window_id,
                               extensions::WindowController::TypeFilter filter,
                               extensions::WindowController** out_controller,
                               std::string* error) {
  DCHECK(out_controller);
  DCHECK(error);

  *out_controller = nullptr;
  if (window_id == extension_misc::kCurrentWindowId) {
    // If there is a window controller associated with this extension, use that.
    if (extensions::WindowController* window_controller =
            function->dispatcher()->GetExtensionWindowController()) {
      *out_controller = window_controller;
      return true;
    }

    // Otherwise get the focused or most recently added window.
    if (extensions::WindowController* window_controller =
            extensions::WindowControllerList::GetInstance()
                ->CurrentWindowForFunctionWithFilter(function, filter)) {
      *out_controller = window_controller;
      return true;
    }

    *error = extensions::ExtensionTabUtil::kNoCurrentWindowError;
    return false;
  } else {
    if (extensions::WindowController* window_controller =
            extensions::WindowControllerList::GetInstance()
                ->FindWindowForFunctionByIdWithFilter(function, window_id,
                                                      filter)) {
      *out_controller = window_controller;
      return true;
    }

    *error = extensions::ErrorUtils::FormatErrorMessage(
        extensions::ExtensionTabUtil::kWindowNotFoundError,
        base::NumberToString(window_id));
    return false;
  }
}

bool CanOperateOnWindow(const ExtensionFunction* function,
                        const extensions::WindowController* controller,
                        extensions::WindowController::TypeFilter filter) {
  if (filter && !controller->MatchesFilter(filter))
    return false;

  // TODO(crbug.com/41367902): Remove this.
  bool allow_dev_tools_windows = !!filter;
  if (function->extension() &&
      !controller->IsVisibleToTabsAPIForExtension(function->extension(),
                                                  allow_dev_tools_windows)) {
    return false;
  }

  if (function->browser_context() == controller->profile())
    return true;

  if (!function->include_incognito_information())
    return false;

  Profile* profile = Profile::FromBrowserContext(function->browser_context());
  return profile->HasPrimaryOTRProfile() &&
         profile->GetPrimaryOTRProfile(/*create_if_needed=*/true) ==
             controller->profile();
}

#if !BUILDFLAG(IS_ANDROID)
// TODO(crbug.com/371432155): Support on Android, specifically the call to
// IsURLAllowedInIncognito() which is part of browser_navigator.h.
IncognitoResult ShouldOpenIncognitoWindow(Profile* profile,
                                          std::optional<bool> incognito,
                                          std::vector<GURL>* urls,
                                          std::string* error) {
  const policy::IncognitoModeAvailability incognito_availability =
      IncognitoModePrefs::GetAvailability(profile->GetPrefs());
  bool incognito_result = false;
  if (incognito.has_value()) {
    incognito_result = incognito.value();
    if (incognito_result && incognito_availability ==
                                policy::IncognitoModeAvailability::kDisabled) {
      *error = extensions::tabs_constants::kIncognitoModeIsDisabled;
      return IncognitoResult::kError;
    }
    if (!incognito_result &&
        incognito_availability == policy::IncognitoModeAvailability::kForced) {
      *error = extensions::tabs_constants::kIncognitoModeIsForced;
      return IncognitoResult::kError;
    }
  } else if (incognito_availability ==
             policy::IncognitoModeAvailability::kForced) {
    // If incognito argument is not specified explicitly, we default to
    // incognito when forced so by policy.
    incognito_result = true;
  }

  // Remove all URLs that are not allowed in an incognito session. Note that a
  // ChromeOS guest session is not considered incognito in this case.
  if (incognito_result && !profile->IsGuestSession()) {
    std::string first_url_erased;
    for (size_t i = 0; i < urls->size();) {
      if (IsURLAllowedInIncognito((*urls)[i])) {
        i++;
      } else {
        if (first_url_erased.empty())
          first_url_erased = (*urls)[i].spec();
        urls->erase(urls->begin() + i);
      }
    }
    if (urls->empty() && !first_url_erased.empty()) {
      *error = extensions::ErrorUtils::FormatErrorMessage(
          extensions::tabs_constants::kURLsNotAllowedInIncognitoError,
          first_url_erased);
      return IncognitoResult::kError;
    }
  }
  return incognito_result ? IncognitoResult::kIncognito
                          : IncognitoResult::kRegular;
}
#endif  // !BUILDFLAG(IS_ANDROID)

}  // namespace windows_util
