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

#include "chrome/browser/profiles/profile_shortcut_manager_win.h"

#include <shlobj.h>  // For SHChangeNotify().
#include <stddef.h>

#include <algorithm>
#include <set>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/path_service.h"
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/win/shortcut.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/shell_integration_win.h"
#include "chrome/browser/win/app_icon.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/chrome_unscaled_resources.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/product.h"
#include "chrome/installer/util/shell_util.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/icon_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_family.h"


using content::BrowserThread;

namespace {

// Name of the badged icon file generated for a given profile.
const char kProfileIconFileName[] = "Google Profile.ico";

// Characters that are not allowed in Windows filenames. Taken from
// http://msdn.microsoft.com/en-us/library/aa365247.aspx
const base::char16 kReservedCharacters[] = L"<>:\"/\\|?*\x01\x02\x03\x04\x05"
    L"\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17"
    L"\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";

// The maximum number of characters allowed in profile shortcuts' file names.
// Warning: migration code will be needed if this is changed later, since
// existing shortcuts might no longer be found if the name is generated
// differently than it was when a shortcut was originally created.
const int kMaxProfileShortcutFileNameLength = 64;

// The avatar badge size needs to be half of the shortcut icon size because
// the Windows taskbar icon is 32x32 and the avatar icon overlay is 16x16. So to
// get the shortcut avatar badge and the avatar icon overlay to match up, we
// need to preserve those ratios when creating the shortcut icon.
const int kShortcutIconSize = 48;
const int kProfileAvatarBadgeSize = kShortcutIconSize / 2;

// Incrementing this number will cause profile icons to be regenerated on
// profile startup (it should be incremented whenever the product/avatar icons
// change, etc).
const int kCurrentProfileIconVersion = 4;

// 2x sized profile avatar icons. Mirrors |kDefaultAvatarIconResources| in
// profile_info_cache.cc.
const int kProfileAvatarIconResources2x[] = {
  IDR_PROFILE_AVATAR_2X_0,
  IDR_PROFILE_AVATAR_2X_1,
  IDR_PROFILE_AVATAR_2X_2,
  IDR_PROFILE_AVATAR_2X_3,
  IDR_PROFILE_AVATAR_2X_4,
  IDR_PROFILE_AVATAR_2X_5,
  IDR_PROFILE_AVATAR_2X_6,
  IDR_PROFILE_AVATAR_2X_7,
  IDR_PROFILE_AVATAR_2X_8,
  IDR_PROFILE_AVATAR_2X_9,
  IDR_PROFILE_AVATAR_2X_10,
  IDR_PROFILE_AVATAR_2X_11,
  IDR_PROFILE_AVATAR_2X_12,
  IDR_PROFILE_AVATAR_2X_13,
  IDR_PROFILE_AVATAR_2X_14,
  IDR_PROFILE_AVATAR_2X_15,
  IDR_PROFILE_AVATAR_2X_16,
  IDR_PROFILE_AVATAR_2X_17,
  IDR_PROFILE_AVATAR_2X_18,
  IDR_PROFILE_AVATAR_2X_19,
  IDR_PROFILE_AVATAR_2X_20,
  IDR_PROFILE_AVATAR_2X_21,
  IDR_PROFILE_AVATAR_2X_22,
  IDR_PROFILE_AVATAR_2X_23,
  IDR_PROFILE_AVATAR_2X_24,
  IDR_PROFILE_AVATAR_2X_25,
  IDR_PROFILE_AVATAR_2X_26,
};

// Badges |app_icon_bitmap| with |avatar_bitmap| at the bottom right corner and
// returns the resulting SkBitmap.
SkBitmap BadgeIcon(const SkBitmap& app_icon_bitmap,
                   const SkBitmap& avatar_bitmap,
                   int scale_factor) {
  SkBitmap source_bitmap =
      profiles::GetAvatarIconAsSquare(avatar_bitmap, scale_factor);
  int avatar_badge_size = kProfileAvatarBadgeSize;
  if (app_icon_bitmap.width() != kShortcutIconSize) {
    avatar_badge_size =
        app_icon_bitmap.width() * kProfileAvatarBadgeSize / kShortcutIconSize;
  }
  SkBitmap sk_icon = skia::ImageOperations::Resize(
      source_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, avatar_badge_size,
      source_bitmap.height() * avatar_badge_size / source_bitmap.width());

  // Overlay the avatar on the icon, anchoring it to the bottom-right of the
  // icon.
  SkBitmap badged_bitmap;
  badged_bitmap.allocN32Pixels(app_icon_bitmap.width(),
                               app_icon_bitmap.height());
  SkCanvas offscreen_canvas(badged_bitmap);
  offscreen_canvas.clear(SK_ColorTRANSPARENT);

  offscreen_canvas.drawBitmap(app_icon_bitmap, 0, 0);
  offscreen_canvas.drawBitmap(sk_icon,
                              app_icon_bitmap.width() - sk_icon.width(),
                              app_icon_bitmap.height() - sk_icon.height());
  return badged_bitmap;
}

// Updates the preferences with the current icon version on icon creation
// success.
void OnProfileIconCreateSuccess(base::FilePath profile_path) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!g_browser_process->profile_manager())
    return;
  Profile* profile =
      g_browser_process->profile_manager()->GetProfileByPath(profile_path);
  if (profile) {
    profile->GetPrefs()->SetInteger(prefs::kProfileIconVersion,
                                    kCurrentProfileIconVersion);
  }
}

// Creates a desktop shortcut icon file (.ico) on the disk for a given profile,
// badging the browser distribution icon with the profile avatar.
// Returns a path to the shortcut icon file on disk, which is empty if this
// fails. Use index 0 when assigning the resulting file as the icon. If both
// given bitmaps are empty, an unbadged icon is created.
// Returns the path to the created icon on success and an empty base::FilePath
// on failure.
// TODO(calamity): Ideally we'd just copy the app icon verbatim from the exe's
// resources in the case of an unbadged icon.
base::FilePath CreateOrUpdateShortcutIconForProfile(
    const base::FilePath& profile_path,
    const SkBitmap& avatar_bitmap_1x,
    const SkBitmap& avatar_bitmap_2x) {
  base::ThreadRestrictions::AssertIOAllowed();

  if (!base::PathExists(profile_path))
    return base::FilePath();

  std::unique_ptr<gfx::ImageFamily> family = GetAppIconImageFamily();
  if (!family)
    return base::FilePath();

  // TODO(mgiuca): A better approach would be to badge each image in the
  // ImageFamily (scaling the badge to the correct size), and then re-export the
  // family (as opposed to making a family with just 48 and 256, then scaling
  // those images to about a dozen different sizes).
  SkBitmap app_icon_bitmap =
      family->CreateExact(kShortcutIconSize, kShortcutIconSize).AsBitmap();
  if (app_icon_bitmap.isNull())
    return base::FilePath();

  gfx::ImageFamily badged_bitmaps;
  if (!avatar_bitmap_1x.empty()) {
    badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
        BadgeIcon(app_icon_bitmap, avatar_bitmap_1x, 1)));
  }

  SkBitmap large_app_icon_bitmap =
      family->CreateExact(IconUtil::kLargeIconSize, IconUtil::kLargeIconSize)
          .AsBitmap();
  if (!large_app_icon_bitmap.isNull() && !avatar_bitmap_2x.empty()) {
    badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(
        BadgeIcon(large_app_icon_bitmap, avatar_bitmap_2x, 2)));
  }

  // If we have no badged bitmaps, we should just use the default chrome icon.
  if (badged_bitmaps.empty()) {
    badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(app_icon_bitmap));
    if (!large_app_icon_bitmap.isNull()) {
      badged_bitmaps.Add(gfx::Image::CreateFrom1xBitmap(large_app_icon_bitmap));
    }
  }
  // Finally, write the .ico file containing this new bitmap.
  const base::FilePath icon_path =
      profiles::internal::GetProfileIconPath(profile_path);
  const bool had_icon = base::PathExists(icon_path);

  if (!IconUtil::CreateIconFileFromImageFamily(badged_bitmaps, icon_path)) {
    // This can happen if the profile directory is deleted between the beginning
    // of this function and here.
    return base::FilePath();
  }

  if (had_icon) {
    // This invalidates the Windows icon cache and causes the icon changes to
    // register with the taskbar and desktop. SHCNE_ASSOCCHANGED will cause a
    // desktop flash and we would like to avoid that if possible.
    SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
  } else {
    SHChangeNotify(SHCNE_CREATE, SHCNF_PATH, icon_path.value().c_str(), NULL);
  }
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&OnProfileIconCreateSuccess, profile_path));
  return icon_path;
}

// Gets the user and system directories for desktop shortcuts. Parameters may
// be NULL if a directory type is not needed. Returns true on success.
bool GetDesktopShortcutsDirectories(
    base::FilePath* user_shortcuts_directory,
    base::FilePath* system_shortcuts_directory) {
  BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
  if (user_shortcuts_directory &&
      !ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
                                  distribution, ShellUtil::CURRENT_USER,
                                  user_shortcuts_directory)) {
    NOTREACHED();
    return false;
  }
  if (system_shortcuts_directory &&
      !ShellUtil::GetShortcutPath(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
                                  distribution, ShellUtil::SYSTEM_LEVEL,
                                  system_shortcuts_directory)) {
    NOTREACHED();
    return false;
  }
  return true;
}

// Returns the long form of |path|, which will expand any shortened components
// like "foo~2" to their full names.
base::FilePath ConvertToLongPath(const base::FilePath& path) {
  const size_t length = GetLongPathName(path.value().c_str(), NULL, 0);
  if (length != 0 && length != path.value().length()) {
    std::vector<wchar_t> long_path(length);
    if (GetLongPathName(path.value().c_str(), &long_path[0], length) != 0)
      return base::FilePath(&long_path[0]);
  }
  return path;
}

// Returns true if the file at |path| is a Chrome shortcut and returns its
// command line in output parameter |command_line|.
bool IsChromeShortcut(const base::FilePath& path,
                      const base::FilePath& chrome_exe,
                      base::string16* command_line) {
  base::ThreadRestrictions::AssertIOAllowed();

  if (path.Extension() != installer::kLnkExt)
    return false;

  base::FilePath target_path;
  if (!base::win::ResolveShortcut(path, &target_path, command_line))
    return false;
  // One of the paths may be in short (elided) form. Compare long paths to
  // ensure these are still properly matched.
  return ConvertToLongPath(target_path) == ConvertToLongPath(chrome_exe);
}

// A functor checks if |path| is the Chrome desktop shortcut (|chrome_exe|)
// that have the specified |command_line|. If |include_empty_command_lines| is
// true Chrome desktop shortcuts with empty command lines will also be included.
struct ChromeCommandLineFilter {
  const base::FilePath& chrome_exe;
  const base::string16& command_line;
  bool include_empty_command_lines;

  ChromeCommandLineFilter(const base::FilePath& chrome_exe,
                          const base::string16& command_line,
                          bool include_empty_command_lines)
      : chrome_exe(chrome_exe),
        command_line(command_line),
        include_empty_command_lines(include_empty_command_lines) {}

  bool operator()(const base::FilePath& path) const {
    base::string16 shortcut_command_line;
    if (!IsChromeShortcut(path, chrome_exe, &shortcut_command_line))
      return false;

    // TODO(asvitkine): Change this to build a CommandLine object and ensure all
    // args from |command_line| are present in the shortcut's CommandLine. This
    // will be more robust when |command_line| contains multiple args.
    if ((shortcut_command_line.empty() && include_empty_command_lines) ||
        (shortcut_command_line.find(command_line) != base::string16::npos)) {
      return true;
    }
    return false;
  }
};

// Get the file paths of desktop files and folders optionally filtered
// by |filter|.
std::set<base::FilePath> ListUserDesktopContents(
    const ChromeCommandLineFilter* filter) {
  std::set<base::FilePath> result;

  base::FilePath user_shortcuts_directory;
  if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, nullptr))
    return result;

  base::FileEnumerator enumerator(
      user_shortcuts_directory, false,
      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
  for (base::FilePath path = enumerator.Next(); !path.empty();
       path = enumerator.Next()) {
    if (!filter || (*filter)(path))
      result.insert(path);
  }
  return result;
}

// Renames the given desktop shortcut and informs the shell of this change.
bool RenameDesktopShortcut(const base::FilePath& old_shortcut_path,
                           const base::FilePath& new_shortcut_path) {
  if (!base::Move(old_shortcut_path, new_shortcut_path))
    return false;

  // Notify the shell of the rename, which allows the icon to keep its position
  // on the desktop when renamed. Note: This only works if either SHCNF_FLUSH or
  // SHCNF_FLUSHNOWAIT is specified as a flag.
  SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATH | SHCNF_FLUSHNOWAIT,
                 old_shortcut_path.value().c_str(),
                 new_shortcut_path.value().c_str());
  return true;
}

// Renames an existing Chrome desktop profile shortcut.
// |profile_shortcuts| are Chrome desktop shortcuts for the profile (there can
// be several).
// |desktop_contents| is the collection of all user desktop shortcuts
// (not only Chrome). It is used to make an unique shortcut for the
// |new_profile_name| among all shortcuts.
// This function updates |profile_shortcuts| and |desktop_contents| respectively
// when renaming occurs.
void RenameChromeDesktopShortcutForProfile(
    const base::string16& old_profile_name,
    const base::string16& new_profile_name,
    std::set<base::FilePath>* profile_shortcuts,
    std::set<base::FilePath>* desktop_contents) {
  DCHECK(profile_shortcuts);
  DCHECK(desktop_contents);
  base::ThreadRestrictions::AssertIOAllowed();

  base::FilePath user_shortcuts_directory;
  base::FilePath system_shortcuts_directory;
  if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory,
                                      &system_shortcuts_directory)) {
    return;
  }

  BrowserDistribution* distribution = BrowserDistribution::GetDistribution();

  // Get a new unique shortcut name.
  const base::string16 new_shortcut_filename =
      profiles::internal::GetUniqueShortcutFilenameForProfile(
          new_profile_name, *desktop_contents, distribution);
  const base::FilePath new_shortcut_path =
      user_shortcuts_directory.Append(new_shortcut_filename);

  if (!profile_shortcuts->empty()) {
    // From all profile_shortcuts choose the one with a known (canonical) name.
    profiles::internal::ShortcutFilenameMatcher matcher(old_profile_name,
                                                        distribution);
    auto it = std::find_if(profile_shortcuts->begin(), profile_shortcuts->end(),
                           [&matcher](const base::FilePath& p) {
                             return matcher.IsCanonical(p.BaseName().value());
                           });
    // If all profile_shortcuts were renamed by user, respect it and do not
    // rename.
    if (it == profile_shortcuts->end())
      return;
    const base::FilePath old_shortcut_path = *it;

    // Rename the old shortcut unless a system-level shortcut exists at the
    // destination, in which case the old shortcut is simply deleted.
    const base::FilePath possible_new_system_shortcut =
        system_shortcuts_directory.Append(new_shortcut_filename);
    if (base::PathExists(possible_new_system_shortcut)) {
      if (base::DeleteFile(old_shortcut_path, false)) {
        profile_shortcuts->erase(old_shortcut_path);
        desktop_contents->erase(old_shortcut_path);
      } else {
        DLOG(ERROR) << "Could not delete Windows profile desktop shortcut.";
      }
    } else {
      if (RenameDesktopShortcut(old_shortcut_path, new_shortcut_path)) {
        profile_shortcuts->erase(old_shortcut_path);
        desktop_contents->erase(old_shortcut_path);
        profile_shortcuts->insert(new_shortcut_path);
        desktop_contents->insert(new_shortcut_path);
      } else {
        DLOG(ERROR) << "Could not rename Windows profile desktop shortcut.";
      }
    }
  } else {
    // If the shortcut does not exist, it may have been deleted by the user.
    // It's also possible that a system-level shortcut exists instead - this
    // should only be the case for the original Chrome shortcut from an
    // installation. If that's the case, copy that one over - it will get its
    // properties updated by
    // |CreateOrUpdateDesktopShortcutsAndIconForProfile()|.
    const auto old_shortcut_filename =
        profiles::internal::GetShortcutFilenameForProfile(old_profile_name,
                                                          distribution);
    const base::FilePath possible_old_system_shortcut =
        system_shortcuts_directory.Append(old_shortcut_filename);
    if (base::PathExists(possible_old_system_shortcut)) {
      if (base::CopyFile(possible_old_system_shortcut, new_shortcut_path)) {
        profile_shortcuts->insert(new_shortcut_path);
        desktop_contents->insert(new_shortcut_path);
      } else {
        DLOG(ERROR) << "Could not copy Windows profile desktop shortcut.";
      }
    }
  }
}

struct CreateOrUpdateShortcutsParams {
  CreateOrUpdateShortcutsParams(
      base::FilePath profile_path,
      ProfileShortcutManagerWin::CreateOrUpdateMode create_mode,
      ProfileShortcutManagerWin::NonProfileShortcutAction action)
      : create_mode(create_mode), action(action), profile_path(profile_path) {}
  ~CreateOrUpdateShortcutsParams() {}

  ProfileShortcutManagerWin::CreateOrUpdateMode create_mode;
  ProfileShortcutManagerWin::NonProfileShortcutAction action;

  // The path for this profile.
  base::FilePath profile_path;
  // The profile name before this update. Empty on create.
  base::string16 old_profile_name;
  // The new profile name.
  base::string16 profile_name;
  // Avatar images for this profile.
  SkBitmap avatar_image_1x;
  SkBitmap avatar_image_2x;
};

// Updates all desktop shortcuts for the given profile to have the specified
// parameters. If |params.create_mode| is CREATE_WHEN_NONE_FOUND, a new shortcut
// is created if no existing ones were found. Whether non-profile shortcuts
// should be updated is specified by |params.action|. File and COM operations
// must be allowed on the calling thread.
void CreateOrUpdateDesktopShortcutsAndIconForProfile(
    const CreateOrUpdateShortcutsParams& params) {
  base::ThreadRestrictions::AssertIOAllowed();

  const base::FilePath shortcut_icon =
      CreateOrUpdateShortcutIconForProfile(params.profile_path,
                                           params.avatar_image_1x,
                                           params.avatar_image_2x);
  if (shortcut_icon.empty() ||
      params.create_mode ==
          ProfileShortcutManagerWin::CREATE_OR_UPDATE_ICON_ONLY) {
    return;
  }

  base::FilePath chrome_exe;
  if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
    NOTREACHED();
    return;
  }

  std::set<base::FilePath> desktop_contents = ListUserDesktopContents(nullptr);

  const base::string16 command_line =
      profiles::internal::CreateProfileShortcutFlags(params.profile_path);
  ChromeCommandLineFilter filter(
      chrome_exe, command_line,
      params.action == ProfileShortcutManagerWin::UPDATE_NON_PROFILE_SHORTCUTS);

  std::set<base::FilePath> shortcuts;
  // Do not call ListUserDesktopContents again (but with filter) to avoid
  // excess work inside it. Just reuse non-filtered desktop_contents.
  // We need both of them (desktop_contents and shortcuts) later.
  std::copy_if(desktop_contents.begin(), desktop_contents.end(),
               std::inserter(shortcuts, shortcuts.begin()), filter);

  if (params.old_profile_name != params.profile_name) {
    RenameChromeDesktopShortcutForProfile(params.old_profile_name,
                                          params.profile_name, &shortcuts,
                                          &desktop_contents);
  }

  ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
  BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
  installer::Product product(distribution);
  product.AddDefaultShortcutProperties(chrome_exe, &properties);


  // Only set the profile-specific properties when |profile_name| is non empty.
  // If it is empty, it means the shortcut being created should be a regular,
  // non-profile Chrome shortcut.
  if (!params.profile_name.empty()) {
    properties.set_arguments(command_line);
    properties.set_icon(shortcut_icon, 0);
  } else {
    // Set the arguments explicitly to the empty string to ensure that
    // |ShellUtil::CreateOrUpdateShortcut| updates that part of the shortcut.
    properties.set_arguments(base::string16());
  }

  properties.set_app_id(shell_integration::win::GetChromiumModelIdForProfile(
      params.profile_path));

  ShellUtil::ShortcutOperation operation =
      ShellUtil::SHELL_SHORTCUT_REPLACE_EXISTING;

  if (params.create_mode == ProfileShortcutManagerWin::CREATE_WHEN_NONE_FOUND &&
      shortcuts.empty()) {
    const base::string16 shortcut_name =
        profiles::internal::GetUniqueShortcutFilenameForProfile(
            params.profile_name, desktop_contents, distribution);
    shortcuts.insert(base::FilePath(shortcut_name));
    operation = ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL;
  }

  for (const auto& shortcut : shortcuts) {
    const base::FilePath shortcut_name = shortcut.BaseName().RemoveExtension();
    properties.set_shortcut_name(shortcut_name.value());
    ShellUtil::CreateOrUpdateShortcut(ShellUtil::SHORTCUT_LOCATION_DESKTOP,
        distribution, properties, operation);
  }
}

// Returns true if any desktop shortcuts exist with target |chrome_exe|,
// regardless of their command line arguments.
bool ChromeDesktopShortcutsExist(const base::FilePath& chrome_exe) {
  base::FilePath user_shortcuts_directory;
  if (!GetDesktopShortcutsDirectories(&user_shortcuts_directory, NULL))
    return false;

  base::FileEnumerator enumerator(user_shortcuts_directory, false,
                                  base::FileEnumerator::FILES);
  for (base::FilePath path = enumerator.Next(); !path.empty();
       path = enumerator.Next()) {
    if (IsChromeShortcut(path, chrome_exe, NULL))
      return true;
  }

  return false;
}

// Deletes all desktop shortcuts for the specified profile. If
// |ensure_shortcuts_remain| is true, then a regular non-profile shortcut will
// be created if this function would otherwise delete the last Chrome desktop
// shortcut(s). File and COM operations must be allowed on the calling thread.
void DeleteDesktopShortcuts(const base::FilePath& profile_path,
                            bool ensure_shortcuts_remain) {
  base::ThreadRestrictions::AssertIOAllowed();

  base::FilePath chrome_exe;
  if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
    NOTREACHED();
    return;
  }

  const base::string16 command_line =
      profiles::internal::CreateProfileShortcutFlags(profile_path);
  ChromeCommandLineFilter filter(chrome_exe, command_line, false);
  const std::set<base::FilePath> shortcuts = ListUserDesktopContents(&filter);

  for (const auto& shortcut : shortcuts) {
    // Use base::DeleteFile() instead of ShellUtil::RemoveShortcuts(), as the
    // latter causes non-profile taskbar shortcuts to be removed since it
    // doesn't consider the command-line of the shortcuts it deletes.
    // TODO(huangs): Refactor with ShellUtil::RemoveShortcuts().
    base::win::UnpinShortcutFromTaskbar(shortcut);
    base::DeleteFile(shortcut, false);
    // Notify the shell that the shortcut was deleted to ensure desktop refresh.
    SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, shortcut.value().c_str(), nullptr);
  }

  // If |ensure_shortcuts_remain| is true and deleting this profile caused the
  // last shortcuts to be removed, re-create a regular non-profile shortcut.
  const bool had_shortcuts = !shortcuts.empty();
  if (ensure_shortcuts_remain && had_shortcuts &&
      !ChromeDesktopShortcutsExist(chrome_exe)) {
    BrowserDistribution* distribution = BrowserDistribution::GetDistribution();
    installer::Product product(distribution);

    ShellUtil::ShortcutProperties properties(ShellUtil::CURRENT_USER);
    product.AddDefaultShortcutProperties(chrome_exe, &properties);
    properties.set_shortcut_name(
        profiles::internal::GetShortcutFilenameForProfile(base::string16(),
                                                          distribution));
    ShellUtil::CreateOrUpdateShortcut(
        ShellUtil::SHORTCUT_LOCATION_DESKTOP, distribution, properties,
        ShellUtil::SHELL_SHORTCUT_CREATE_IF_NO_SYSTEM_LEVEL);
  }
}

// Returns true if profile at |profile_path| has any shortcuts. Does not
// consider non-profile shortcuts. File and COM operations must be allowed on
// the calling thread.
bool HasAnyProfileShortcuts(const base::FilePath& profile_path) {
  base::ThreadRestrictions::AssertIOAllowed();

  base::FilePath chrome_exe;
  if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
    NOTREACHED();
    return false;
  }

  const base::string16 command_line =
      profiles::internal::CreateProfileShortcutFlags(profile_path);
  ChromeCommandLineFilter filter(chrome_exe, command_line, false);
  return !ListUserDesktopContents(&filter).empty();
}

// Replaces any reserved characters with spaces, and trims the resulting string
// to prevent any leading and trailing spaces. Also makes sure that the
// resulting filename doesn't exceed |kMaxProfileShortcutFileNameLength|.
// TODO(macourteau): find a way to limit the total path's length to MAX_PATH
// instead of limiting the profile's name to |kMaxProfileShortcutFileNameLength|
// characters.
base::string16 SanitizeShortcutProfileNameString(
    const base::string16& profile_name) {
  base::string16 sanitized = profile_name;
  size_t pos = sanitized.find_first_of(kReservedCharacters);
  while (pos != base::string16::npos) {
    sanitized[pos] = L' ';
    pos = sanitized.find_first_of(kReservedCharacters, pos + 1);
  }

  base::TrimWhitespace(sanitized, base::TRIM_LEADING, &sanitized);
  if (sanitized.size() > kMaxProfileShortcutFileNameLength)
    sanitized.erase(kMaxProfileShortcutFileNameLength);
  base::TrimWhitespace(sanitized, base::TRIM_TRAILING, &sanitized);

  return sanitized;
}

// Returns a copied SkBitmap for the given image that can be safely passed to
// another thread.
SkBitmap GetSkBitmapCopy(const gfx::Image& image) {
  DCHECK(!image.IsEmpty());
  const SkBitmap* image_bitmap = image.ToSkBitmap();
  SkBitmap bitmap_copy;
  if (bitmap_copy.tryAllocPixels(image_bitmap->info()))
    image_bitmap->readPixels(bitmap_copy.info(), bitmap_copy.getPixels(),
                             bitmap_copy.rowBytes(), 0, 0);
  return bitmap_copy;
}

// Returns a copied SkBitmap for the given resource id that can be safely passed
// to another thread.
SkBitmap GetImageResourceSkBitmapCopy(int resource_id) {
  const gfx::Image image =
      ResourceBundle::GetSharedInstance().GetNativeImageNamed(resource_id);
  return GetSkBitmapCopy(image);
}

}  // namespace

namespace profiles {
namespace internal {

base::FilePath GetProfileIconPath(const base::FilePath& profile_path) {
  return profile_path.AppendASCII(kProfileIconFileName);
}

base::string16 GetShortcutFilenameForProfile(
    const base::string16& profile_name,
    BrowserDistribution* distribution) {
  base::string16 shortcut_name;
  if (!profile_name.empty()) {
    shortcut_name.append(SanitizeShortcutProfileNameString(profile_name));
    shortcut_name.append(L" - ");
    shortcut_name.append(l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME));
  } else {
    shortcut_name.append(distribution->GetShortcutName());
  }
  return shortcut_name + installer::kLnkExt;
}

base::string16 GetUniqueShortcutFilenameForProfile(
    const base::string16& profile_name,
    const std::set<base::FilePath>& excludes,
    BrowserDistribution* distribution) {
  std::set<base::string16> excludes_names;
  std::transform(excludes.begin(), excludes.end(),
                 std::inserter(excludes_names, excludes_names.begin()),
                 [](const base::FilePath& e) { return e.BaseName().value(); });

  const auto base_name =
      GetShortcutFilenameForProfile(profile_name, distribution);
  auto name = base_name;
  const base::FilePath base_path(base_name);
  for (int uniquifier = 1; excludes_names.count(name) > 0; ++uniquifier) {
    const auto suffix = base::StringPrintf(" (%d)", uniquifier);
    name = base_path.InsertBeforeExtensionASCII(suffix).value();
  }
  return name;
}

// Corresponds to GetUniqueShortcutFilenameForProfile.
ShortcutFilenameMatcher::ShortcutFilenameMatcher(
    const base::string16& profile_name,
    BrowserDistribution* distribution)
    : profile_shortcut_filename_(
          GetShortcutFilenameForProfile(profile_name, distribution)),
      lnk_ext_(installer::kLnkExt),
      profile_shortcut_name_(profile_shortcut_filename_) {
  DCHECK(profile_shortcut_name_.ends_with(lnk_ext_));
  profile_shortcut_name_.remove_suffix(lnk_ext_.size());
}

bool ShortcutFilenameMatcher::IsCanonical(
    const base::string16& filename) const {
  if (filename == profile_shortcut_filename_)
    return true;

  base::StringPiece16 shortcut_suffix(filename);
  if (!shortcut_suffix.starts_with(profile_shortcut_name_))
    return false;
  shortcut_suffix.remove_prefix(profile_shortcut_name_.size());

  if (!shortcut_suffix.ends_with(lnk_ext_))
    return false;
  shortcut_suffix.remove_suffix(lnk_ext_.size());

  if (shortcut_suffix.size() < 4 || !shortcut_suffix.starts_with(L" (") ||
      !shortcut_suffix.ends_with(L")")) {
    return false;
  }
  return std::all_of(shortcut_suffix.begin() + 2, shortcut_suffix.end() - 1,
                     iswdigit);
}

base::string16 CreateProfileShortcutFlags(const base::FilePath& profile_path) {
  return base::StringPrintf(L"--%ls=\"%ls\"",
                            base::ASCIIToUTF16(
                                switches::kProfileDirectory).c_str(),
                            profile_path.BaseName().value().c_str());
}

}  // namespace internal
}  // namespace profiles

namespace {
bool disabled_for_unit_tests = false;
}

void ProfileShortcutManager::DisableForUnitTests() {
  disabled_for_unit_tests = true;
}

// static
bool ProfileShortcutManager::IsFeatureEnabled() {
  if (disabled_for_unit_tests)
    return false;

  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kEnableProfileShortcutManager))
    return true;

  base::FilePath user_data_dir;
  bool success = base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  DCHECK(success);
  base::FilePath default_user_data_dir;
  success = chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
  DCHECK(success);
  return user_data_dir == default_user_data_dir;
}

// static
ProfileShortcutManager* ProfileShortcutManager::Create(
    ProfileManager* manager) {
  return new ProfileShortcutManagerWin(manager);
}

ProfileShortcutManagerWin::ProfileShortcutManagerWin(ProfileManager* manager)
    : profile_manager_(manager) {
  DCHECK_EQ(
      arraysize(kProfileAvatarIconResources2x),
      profiles::GetDefaultAvatarIconCount());

  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_CREATED,
                 content::NotificationService::AllSources());

  profile_manager_->GetProfileAttributesStorage().AddObserver(this);
}

ProfileShortcutManagerWin::~ProfileShortcutManagerWin() {
  profile_manager_->GetProfileAttributesStorage().RemoveObserver(this);
}

void ProfileShortcutManagerWin::CreateOrUpdateProfileIcon(
    const base::FilePath& profile_path) {
  CreateOrUpdateShortcutsForProfileAtPath(profile_path,
                                          CREATE_OR_UPDATE_ICON_ONLY,
                                          IGNORE_NON_PROFILE_SHORTCUTS);
}

void ProfileShortcutManagerWin::CreateProfileShortcut(
    const base::FilePath& profile_path) {
  CreateOrUpdateShortcutsForProfileAtPath(profile_path, CREATE_WHEN_NONE_FOUND,
                                          IGNORE_NON_PROFILE_SHORTCUTS);
}

void ProfileShortcutManagerWin::RemoveProfileShortcuts(
    const base::FilePath& profile_path) {
  base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
      ->PostTask(FROM_HERE,
                 base::Bind(&DeleteDesktopShortcuts, profile_path, false));
}

void ProfileShortcutManagerWin::HasProfileShortcuts(
    const base::FilePath& profile_path,
    const base::Callback<void(bool)>& callback) {
  base::PostTaskAndReplyWithResult(
      base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()}).get(),
      FROM_HERE, base::Bind(&HasAnyProfileShortcuts, profile_path), callback);
}

void ProfileShortcutManagerWin::GetShortcutProperties(
    const base::FilePath& profile_path,
    base::CommandLine* command_line,
    base::string16* name,
    base::FilePath* icon_path) {
  base::FilePath chrome_exe;
  if (!PathService::Get(base::FILE_EXE, &chrome_exe)) {
    NOTREACHED();
    return;
  }

  ProfileAttributesStorage& storage =
      profile_manager_->GetProfileAttributesStorage();
  ProfileAttributesEntry* entry;
  bool has_entry = storage.GetProfileAttributesWithPath(profile_path, &entry);
  DCHECK(has_entry);

  // The used profile name should be empty if there is only 1 profile.
  base::string16 shortcut_profile_name;
  if (storage.GetNumberOfProfiles() > 1u)
    shortcut_profile_name = entry->GetName();

  *name = base::FilePath(profiles::internal::GetShortcutFilenameForProfile(
      shortcut_profile_name,
      BrowserDistribution::GetDistribution())).RemoveExtension().value();

  command_line->ParseFromString(L"\"" + chrome_exe.value() + L"\" " +
      profiles::internal::CreateProfileShortcutFlags(profile_path));

  *icon_path = profiles::internal::GetProfileIconPath(profile_path);
}

void ProfileShortcutManagerWin::OnProfileAdded(
    const base::FilePath& profile_path) {
  CreateOrUpdateProfileIcon(profile_path);
  if (profile_manager_->GetProfileAttributesStorage().GetNumberOfProfiles() ==
          2u) {
    // When the second profile is added, make existing non-profile shortcuts
    // point to the first profile and be badged/named appropriately.
    CreateOrUpdateShortcutsForProfileAtPath(GetOtherProfilePath(profile_path),
                                            UPDATE_EXISTING_ONLY,
                                            UPDATE_NON_PROFILE_SHORTCUTS);
  }
}

void ProfileShortcutManagerWin::OnProfileWasRemoved(
    const base::FilePath& profile_path,
    const base::string16& profile_name) {
  ProfileAttributesStorage& storage =
      profile_manager_->GetProfileAttributesStorage();
  // If there is only one profile remaining, remove the badging information
  // from an existing shortcut.
  const bool deleting_down_to_last_profile =
      (storage.GetNumberOfProfiles() == 1u);
  if (deleting_down_to_last_profile) {
    // This is needed to unbadge the icon.
    CreateOrUpdateShortcutsForProfileAtPath(
        storage.GetAllProfilesAttributes().front()->GetPath(),
        UPDATE_EXISTING_ONLY,
        IGNORE_NON_PROFILE_SHORTCUTS);
  }

  base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
      ->PostTask(FROM_HERE, base::Bind(&DeleteDesktopShortcuts, profile_path,
                                       deleting_down_to_last_profile));
}

void ProfileShortcutManagerWin::OnProfileNameChanged(
    const base::FilePath& profile_path,
    const base::string16& old_profile_name) {
  CreateOrUpdateShortcutsForProfileAtPath(profile_path, UPDATE_EXISTING_ONLY,
                                          IGNORE_NON_PROFILE_SHORTCUTS);
}

void ProfileShortcutManagerWin::OnProfileAvatarChanged(
    const base::FilePath& profile_path) {
  CreateOrUpdateProfileIcon(profile_path);
}

base::FilePath ProfileShortcutManagerWin::GetOtherProfilePath(
    const base::FilePath& profile_path) {
  const ProfileAttributesStorage& storage =
      profile_manager_->GetProfileAttributesStorage();
  DCHECK_EQ(2u, storage.GetNumberOfProfiles());
  // Get the index of the current profile, in order to find the index of the
  // other profile.
  std::vector<ProfileAttributesEntry*> entries = g_browser_process->
      profile_manager()->GetProfileAttributesStorage().
          GetAllProfilesAttributes();
  for (ProfileAttributesEntry* entry : entries) {
    base::FilePath path = entry->GetPath();
    if (path != profile_path)
      return path;
  }
  NOTREACHED();
  return base::FilePath();
}

void ProfileShortcutManagerWin::CreateOrUpdateShortcutsForProfileAtPath(
    const base::FilePath& profile_path,
    CreateOrUpdateMode create_mode,
    NonProfileShortcutAction action) {
  DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
         BrowserThread::CurrentlyOn(BrowserThread::UI));
  CreateOrUpdateShortcutsParams params(profile_path, create_mode, action);

  ProfileAttributesStorage& storage =
      profile_manager_->GetProfileAttributesStorage();
  ProfileAttributesEntry* entry;
  bool has_entry = storage.GetProfileAttributesWithPath(profile_path, &entry);
  if (!has_entry)
    return;
  bool remove_badging = (storage.GetNumberOfProfiles() == 1u);

  params.old_profile_name =
      entry->GetShortcutName();

  // Exit early if the mode is to update existing profile shortcuts only and
  // none were ever created for this profile, per the shortcut name not being
  // set in the profile attributes storage.
  if (params.old_profile_name.empty() &&
      create_mode == UPDATE_EXISTING_ONLY &&
      action == IGNORE_NON_PROFILE_SHORTCUTS) {
    return;
  }

  if (!remove_badging) {
    params.profile_name = entry->GetName();

    // The profile might be using the Gaia avatar, which is not in the
    // resources array.
    bool has_gaia_image = false;
    if (entry->IsUsingGAIAPicture()) {
      const gfx::Image* image = entry->GetGAIAPicture();
      if (image) {
        params.avatar_image_1x = GetSkBitmapCopy(*image);
        // Gaia images are 256px, which makes them big enough to use in the
        // large icon case as well.
        DCHECK_GE(image->Width(), IconUtil::kLargeIconSize);
        params.avatar_image_2x = params.avatar_image_1x;
        has_gaia_image = true;
      }
    }

    // If the profile isn't using a Gaia image, or if the Gaia image did not
    // exist, revert to the previously used avatar icon.
    if (!has_gaia_image) {
      const size_t icon_index = entry->GetAvatarIconIndex();
      const int resource_id_1x =
          profiles::GetDefaultAvatarIconResourceIDAtIndex(icon_index);
      const int resource_id_2x = kProfileAvatarIconResources2x[icon_index];
      // Make a copy of the SkBitmaps to ensure that we can safely use the image
      // data on the thread we post to.
      params.avatar_image_1x = GetImageResourceSkBitmapCopy(resource_id_1x);
      params.avatar_image_2x = GetImageResourceSkBitmapCopy(resource_id_2x);
    }
  }
  base::CreateCOMSTATaskRunnerWithTraits({base::MayBlock()})
      ->PostTask(
          FROM_HERE,
          base::Bind(&CreateOrUpdateDesktopShortcutsAndIconForProfile, params));

  entry->SetShortcutName(params.profile_name);
}

void ProfileShortcutManagerWin::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  DCHECK_EQ(chrome::NOTIFICATION_PROFILE_CREATED, type);

  Profile* profile =
      content::Source<Profile>(source).ptr()->GetOriginalProfile();
  if (profile->GetPrefs()->GetInteger(prefs::kProfileIconVersion) <
      kCurrentProfileIconVersion) {
    // Ensure the profile's icon file has been created.
    CreateOrUpdateProfileIcon(profile->GetPath());
  }
}
