// 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/browser_window_state.h"

#include <stddef.h>

#include <string_view>
#include <utility>

#include "base/command_line.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/buildflags.h"
#include "chrome/browser/defaults.h"
#include "chrome/browser/sessions/session_service_base.h"
#include "chrome/browser/sessions/session_service_lookup.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/window_sizer/window_sizer.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "ui/base/mojom/window_show_state.mojom.h"

namespace chrome {
namespace {

// Parse two comma-separated integers from str. Return true on success.
bool ParseCommaSeparatedIntegers(const std::string& str,
                                 int* ret_num1,
                                 int* ret_num2) {
  const size_t comma = str.find(',');
  if (comma == std::string::npos) {
    return false;
  }
  auto view = std::string_view(str);
  return base::StringToInt(view.substr(0, comma), ret_num1) &&
         base::StringToInt(view.substr(comma + 1), ret_num2);
}

}  // namespace

std::string GetWindowName(const Browser* browser) {
  switch (browser->type()) {
    case Browser::TYPE_NORMAL:
#if BUILDFLAG(IS_CHROMEOS)
    case Browser::TYPE_CUSTOM_TAB:
#endif
      return prefs::kBrowserWindowPlacement;
    case Browser::TYPE_POPUP:
    case Browser::TYPE_PICTURE_IN_PICTURE:
      return prefs::kBrowserWindowPlacementPopup;
    case Browser::TYPE_APP:
    case Browser::TYPE_DEVTOOLS:
      return browser->app_name();
    case Browser::TYPE_APP_POPUP:
      return browser->app_name() + "_popup";
  }
}

base::Value::Dict& GetWindowPlacementDictionaryReadWrite(
    const std::string& window_name,
    PrefService* prefs,
    std::unique_ptr<ScopedDictPrefUpdate>& scoped_update) {
  DCHECK(!window_name.empty());
  // Non-app window placements each use their own per-window-name dictionary
  // preference, so can make a ScopedDictPrefUpdate for the relevant preference,
  // and return its dictionary directly.
  if (prefs->FindPreference(window_name)) {
    scoped_update = std::make_unique<ScopedDictPrefUpdate>(prefs, window_name);
    return scoped_update->Get();
  }

  // The window placements for all apps are stored in a single dictionary
  // preference, with per-window-name nested dictionaries, so need to make
  // ScopedDictPrefUpdate and then find the relevant dictionary within it, based
  // on window name.
  scoped_update =
      std::make_unique<ScopedDictPrefUpdate>(prefs, prefs::kAppWindowPlacement);
  base::Value::Dict* this_app_dict =
      (*scoped_update)->FindDictByDottedPath(window_name);
  if (this_app_dict) {
    return *this_app_dict;
  }
  return (*scoped_update)
      ->SetByDottedPath(window_name, base::Value::Dict())
      ->GetDict();
}

const base::Value::Dict* GetWindowPlacementDictionaryReadOnly(
    const std::string& window_name,
    PrefService* prefs) {
  DCHECK(!window_name.empty());
  if (prefs->FindPreference(window_name)) {
    return &prefs->GetDict(window_name);
  }

  const base::Value::Dict& app_windows =
      prefs->GetDict(prefs::kAppWindowPlacement);
  return app_windows.FindDict(window_name);
}

bool ShouldSaveWindowPlacement(const Browser* browser) {
  // Never track app windows that do not have a trusted source (i.e. windows
  // spawned by an app).  See similar code in
  // SessionServiceBase::ShouldTrackBrowser().
  return !(browser->is_type_app() || browser->is_type_app_popup()) ||
         browser->is_trusted_source();
}

bool SavedBoundsAreContentBounds(const Browser* browser) {
  // Applications other than web apps (such as devtools) save their window size.
  // Web apps, on the other hand, have the same behavior as popups, and save
  // their content bounds.
  return !browser->is_type_normal() && !browser->is_type_devtools() &&
         !browser->is_trusted_source();
}

void SaveWindowPlacement(const Browser* browser,
                         const gfx::Rect& bounds,
                         ui::mojom::WindowShowState show_state) {
  // Save to the session storage service, used when reloading a past session.
  // Note that we don't want to be the ones who cause lazy initialization of
  // the session service. This function gets called during initial window
  // showing, and we don't want to bring in the session service this early.
  SessionServiceBase* service = GetAppropriateSessionServiceIfExisting(browser);
  if (service) {
    service->SetWindowBounds(browser->session_id(), bounds, show_state);
  }
}

void SaveWindowWorkspace(const Browser* browser, const std::string& workspace) {
  SessionServiceBase* service = GetAppropriateSessionServiceIfExisting(browser);
  if (service) {
    service->SetWindowWorkspace(browser->session_id(), workspace);
  }
}

void SaveWindowVisibleOnAllWorkspaces(const Browser* browser,
                                      bool visible_on_all_workspaces) {
  SessionServiceBase* service = GetAppropriateSessionServiceIfExisting(browser);
  if (service) {
    service->SetWindowVisibleOnAllWorkspaces(browser->session_id(),
                                             visible_on_all_workspaces);
  }
}

void GetSavedWindowBoundsAndShowState(const Browser* browser,
                                      gfx::Rect* bounds,
                                      ui::mojom::WindowShowState* show_state) {
  DCHECK(browser);
  DCHECK(bounds);
  DCHECK(show_state);
  *bounds = browser->override_bounds();
  WindowSizer::GetBrowserWindowBoundsAndShowState(*bounds, browser, bounds,
                                                  show_state);

  const base::CommandLine& parsed_command_line =
      *base::CommandLine::ForCurrentProcess();

  internal::UpdateWindowBoundsAndShowStateFromCommandLine(parsed_command_line,
                                                          bounds, show_state);
}

namespace internal {

void UpdateWindowBoundsAndShowStateFromCommandLine(
    const base::CommandLine& command_line,
    gfx::Rect* bounds,
    ui::mojom::WindowShowState* show_state) {
  // Allow command-line flags to override the window size and position. If
  // either of these is specified then set the show state to NORMAL so that
  // they are immediately respected.
  if (command_line.HasSwitch(switches::kWindowSize)) {
    std::string str = command_line.GetSwitchValueASCII(switches::kWindowSize);
    int width, height;
    if (ParseCommaSeparatedIntegers(str, &width, &height)) {
      bounds->set_size(gfx::Size(width, height));
      *show_state = ui::mojom::WindowShowState::kNormal;
    }
  }
  if (command_line.HasSwitch(switches::kWindowPosition)) {
    std::string str =
        command_line.GetSwitchValueASCII(switches::kWindowPosition);
    int x, y;
    if (ParseCommaSeparatedIntegers(str, &x, &y)) {
      bounds->set_origin(gfx::Point(x, y));
      *show_state = ui::mojom::WindowShowState::kNormal;
    }
  }
}

}  // namespace internal

}  // namespace chrome
