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

#include <stddef.h>

#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_shortcut_win.h"
#include "base/win/scoped_com_initializer.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/shortcuts/platform_util_win.h"
#include "chrome/browser/web_applications/web_app_helpers.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/install_static/install_util.h"
#include "chrome/installer/util/install_util.h"
#include "chrome/installer/util/shell_util.h"
#include "chrome/installer/util/util_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace shell_integration {
namespace win {

namespace {

struct ShortcutTestObject {
  base::FilePath path;
  base::win::ShortcutProperties properties;
};

class ShellIntegrationWinMigrateShortcutTest : public testing::Test {
 public:
  ShellIntegrationWinMigrateShortcutTest(
      const ShellIntegrationWinMigrateShortcutTest&) = delete;
  ShellIntegrationWinMigrateShortcutTest& operator=(
      const ShellIntegrationWinMigrateShortcutTest&) = delete;

 protected:
  ShellIntegrationWinMigrateShortcutTest() = default;

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(
        temp_dir_sub_dir_.CreateUniqueTempDirUnderPath(temp_dir_.GetPath()));
    // A path to a random target.
    base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &other_target_);

    // This doesn't need to actually have a base name of "chrome.exe".
    base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &chrome_exe_);

    chrome_app_id_ = ShellUtil::GetBrowserModelId(true);

    base::FilePath default_user_data_dir;
    chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
    base::FilePath default_profile_path =
        default_user_data_dir.AppendASCII(chrome::kInitialProfile);
    non_default_user_data_dir_ = base::FilePath(FILE_PATH_LITERAL("root"))
        .Append(FILE_PATH_LITERAL("Non Default Data Dir"));
    non_default_profile_ = L"NonDefault";
    non_default_profile_chrome_app_id_ = GetAppUserModelIdForBrowser(
        default_user_data_dir.Append(non_default_profile_));
    non_default_user_data_dir_chrome_app_id_ = GetAppUserModelIdForBrowser(
        non_default_user_data_dir_.AppendASCII(chrome::kInitialProfile));
    non_default_user_data_dir_and_profile_chrome_app_id_ =
        GetAppUserModelIdForBrowser(
            non_default_user_data_dir_.Append(non_default_profile_));

    extension_id_ = L"chromiumexampleappidforunittests";
    std::wstring app_name =
        base::UTF8ToWide(web_app::GenerateApplicationNameFromAppId(
            base::WideToUTF8(extension_id_)));
    extension_app_id_ = GetAppUserModelIdForApp(app_name, default_profile_path);
    non_default_profile_extension_app_id_ = GetAppUserModelIdForApp(
        app_name, default_user_data_dir.Append(non_default_profile_));
  }

  // Creates a test shortcut corresponding to |shortcut_properties| and resets
  // |shortcut_properties| after copying it to an internal structure for later
  // verification.
  void AddTestShortcutAndResetProperties(
      const base::FilePath& shortcut_dir,
      base::win::ShortcutProperties* shortcut_properties) {
    ShortcutTestObject shortcut_test_object;
    base::FilePath shortcut_path = shortcut_dir.Append(
        L"Shortcut " + base::NumberToWString(shortcuts_.size()) +
        installer::kLnkExt);
    shortcut_test_object.path = shortcut_path;
    shortcut_test_object.properties = *shortcut_properties;
    shortcuts_.push_back(shortcut_test_object);
    ASSERT_TRUE(base::win::CreateOrUpdateShortcutLink(
        shortcut_path, *shortcut_properties,
        base::win::ShortcutOperation::kCreateAlways));
    shortcut_properties->options = 0U;
  }

  void CreateShortcuts() {
    // A temporary object to pass properties to
    // AddTestShortcutAndResetProperties().
    base::win::ShortcutProperties temp_properties;

    // Shortcut 0 doesn't point to chrome.exe and thus should never be migrated.
    temp_properties.set_target(other_target_);
    temp_properties.set_app_id(L"Dumbo");
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 1 points to chrome.exe and thus should be migrated.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 2 points to chrome.exe, but already has the right appid.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(chrome_app_id_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 3 is like shortcut 1, but it's appid is a prefix of the expected
    // appid instead of being totally different.
    std::wstring chrome_app_id_is_prefix(chrome_app_id_);
    chrome_app_id_is_prefix.push_back(L'1');
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(chrome_app_id_is_prefix);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 4 is like shortcut 1, but it's appid is of the same size as the
    // expected appid.
    std::wstring same_size_as_chrome_app_id(chrome_app_id_.size(), L'1');
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(same_size_as_chrome_app_id);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 5 doesn't have an app_id, it should
    // be set as expected upon migration.
    temp_properties.set_target(chrome_exe_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 6 has a non-default profile directory and so should get a non-
    // default app id.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    temp_properties.set_arguments(
        L"--profile-directory=" + non_default_profile_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 7 has a non-default user data directory and so should get a non-
    // default app id.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    temp_properties.set_arguments(
        L"--user-data-dir=\"" + non_default_user_data_dir_.value() + L"\"");
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 8 has a non-default user data directory as well as a non-default
    // profile directory and so should get a non-default app id.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    temp_properties.set_arguments(
        L"--user-data-dir=\"" + non_default_user_data_dir_.value() + L"\" " +
        L"--profile-directory=" + non_default_profile_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 9 is a shortcut to an app and should get an app id for that app
    // rather than the chrome app id.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    temp_properties.set_arguments(
        L"--app-id=" + extension_id_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 10 is a shortcut to an app with a non-default profile and should
    // get an app id for that app with a non-default app id rather than the
    // chrome app id.
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(L"Dumbo");
    temp_properties.set_arguments(
        L"--app-id=" + extension_id_ +
        L" --profile-directory=" + non_default_profile_);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));

    // Shortcut 11 is like shortcut 1, but it's appid explicitly includes the
    // default profile.
    std::wstring chrome_app_id_with_default_profile =
        chrome_app_id_ + L".Default";
    temp_properties.set_target(chrome_exe_);
    temp_properties.set_app_id(chrome_app_id_with_default_profile);
    ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
        temp_dir_.GetPath(), &temp_properties));
  }

  base::win::ScopedCOMInitializer com_initializer_;

  base::ScopedTempDir temp_dir_;

  // Used to test migration of shortcuts in ImplicitApps sub-directories.
  base::ScopedTempDir temp_dir_sub_dir_;

  // Test shortcuts.
  std::vector<ShortcutTestObject> shortcuts_;

  // The path to a fake chrome.exe.
  base::FilePath chrome_exe_;

  // The path to a random target.
  base::FilePath other_target_;

  // Chrome's AppUserModelId.
  std::wstring chrome_app_id_;

  // A profile that isn't the Default profile.
  std::wstring non_default_profile_;

  // A user data dir that isn't the default.
  base::FilePath non_default_user_data_dir_;

  // Chrome's AppUserModelId for the non-default profile.
  std::wstring non_default_profile_chrome_app_id_;

  // Chrome's AppUserModelId for the non-default user data dir.
  std::wstring non_default_user_data_dir_chrome_app_id_;

  // Chrome's AppUserModelId for the non-default user data dir and non-default
  // profile.
  std::wstring non_default_user_data_dir_and_profile_chrome_app_id_;

  // An example extension id of an example app.
  std::wstring extension_id_;

  // The app id of the example app for the default profile and user data dir.
  std::wstring extension_app_id_;

  // The app id of the example app for the non-default profile.
  std::wstring non_default_profile_extension_app_id_;
};

}  // namespace

TEST_F(ShellIntegrationWinMigrateShortcutTest, AdjustAppIds) {
  CreateShortcuts();
  // 10 shortcuts should have their app id updated below.
  EXPECT_EQ(10,
            MigrateShortcutsInPathInternal(chrome_exe_, temp_dir_.GetPath()));

  // Shortcut 1, 3, 4, 5, 6, 7, 8, 9, 10, and 11 should have had their app_id
  //  fixed.
  shortcuts_[1].properties.set_app_id(chrome_app_id_);
  shortcuts_[3].properties.set_app_id(chrome_app_id_);
  shortcuts_[4].properties.set_app_id(chrome_app_id_);
  shortcuts_[5].properties.set_app_id(chrome_app_id_);
  shortcuts_[6].properties.set_app_id(non_default_profile_chrome_app_id_);
  shortcuts_[7].properties.set_app_id(non_default_user_data_dir_chrome_app_id_);
  shortcuts_[8].properties.set_app_id(
      non_default_user_data_dir_and_profile_chrome_app_id_);
  shortcuts_[9].properties.set_app_id(extension_app_id_);
  shortcuts_[10].properties.set_app_id(non_default_profile_extension_app_id_);
  shortcuts_[11].properties.set_app_id(chrome_app_id_);

  for (size_t i = 0; i < shortcuts_.size(); ++i) {
    SCOPED_TRACE(i);
    base::win::ValidateShortcut(shortcuts_[i].path, shortcuts_[i].properties);
  }

  // Make sure shortcuts are not re-migrated.
  EXPECT_EQ(0,
            MigrateShortcutsInPathInternal(chrome_exe_, temp_dir_.GetPath()));
}

// Test that chrome_proxy.exe shortcuts (PWA) have their app_id migrated
// to not include the default profile name. This tests both shortcuts in the
// DIR_TASKBAR_PINS and sub-directories of DIR_IMPLICIT_APP_SHORTCUTS.
TEST_F(ShellIntegrationWinMigrateShortcutTest, MigrateChromeProxyTest) {
  // Create shortcut to chrome_proxy_exe in executable directory,
  // using the default profile, with the AppModelId not containing the
  // profile name.
  base::win::ShortcutProperties temp_properties;
  temp_properties.set_target(shortcuts::GetChromeProxyPath());
  temp_properties.set_app_id(L"Dumbo.Default");
  ASSERT_NO_FATAL_FAILURE(
      AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
  temp_properties.set_target(shortcuts::GetChromeProxyPath());
  temp_properties.set_app_id(L"Dumbo2.Default");
  ASSERT_NO_FATAL_FAILURE(AddTestShortcutAndResetProperties(
      temp_dir_sub_dir_.GetPath(), &temp_properties));

  // Check that a chrome proxy shortcut whose app_id is just the extension app
  // id has its AUMI migrated to start with the browser's app_id.
  // It technically doesn't matter what ShortcutProperties's app_id is,
  // since the migration is based on ShortcutProperties.arguments.
  temp_properties.set_target(shortcuts::GetChromeProxyPath());
  temp_properties.set_app_id(L"Dumbo3.Default");
  base::CommandLine cmd_line = shell_integration::CommandLineArgsForLauncher(
      GURL(), base::WideToUTF8(extension_id_), base::FilePath(), "");
  ASSERT_EQ(cmd_line.GetCommandLineString(), L" --app-id=" + extension_id_);
  temp_properties.set_arguments(cmd_line.GetCommandLineString());
  ASSERT_NO_FATAL_FAILURE(
      AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));

  // Check that a chrome proxy shortcut with a kApp url in its command line
  // has its AUMI migrated to start with the browser's app_id.
  temp_properties.set_target(shortcuts::GetChromeProxyPath());
  temp_properties.set_app_id(L"Dumbo4.Default");
  GURL url("http://www.example.com");
  cmd_line = shell_integration::CommandLineArgsForLauncher(
      url, std::string(), base::FilePath(), "");
  ASSERT_EQ(cmd_line.GetCommandLineString(), L" --app=http://www.example.com/");
  temp_properties.set_arguments(cmd_line.GetCommandLineString());
  ASSERT_NO_FATAL_FAILURE(
      AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));

  MigrateTaskbarPinsCallback(temp_dir_.GetPath(), temp_dir_.GetPath());
  // Verify that the migrated shortcut in temp_dir_ does not contain the default
  // profile name.
  shortcuts_[0].properties.set_app_id(chrome_app_id_);
  base::win::ValidateShortcut(shortcuts_[0].path, shortcuts_[0].properties);
  // Verify that the migrated shortcut in temp_dir_sub does not contain the
  // default profile name.
  shortcuts_[1].properties.set_app_id(chrome_app_id_);
  base::win::ValidateShortcut(shortcuts_[1].path, shortcuts_[1].properties);

  shortcuts_[2].properties.set_app_id(extension_app_id_);
  base::win::ValidateShortcut(shortcuts_[2].path, shortcuts_[2].properties);

  shortcuts_[3].properties.set_app_id(GetAppUserModelIdForApp(
      base::UTF8ToWide(web_app::GenerateApplicationNameFromURL(url)),
      base::FilePath()));
  base::win::ValidateShortcut(shortcuts_[3].path, shortcuts_[3].properties);
}

// This test verifies that MigrateTaskbarPins does a case-insensitive
// comparison when comparing the shortcut target with the chrome exe path.
TEST_F(ShellIntegrationWinMigrateShortcutTest, MigrateMixedCaseDirTest) {
  base::win::ShortcutProperties temp_properties;
  base::FilePath chrome_proxy_path(shortcuts::GetChromeProxyPath());
  ASSERT_EQ(chrome_proxy_path.Extension(), FILE_PATH_LITERAL(".exe"));
  temp_properties.set_target(
      chrome_proxy_path.ReplaceExtension(FILE_PATH_LITERAL("EXE")));
  temp_properties.set_app_id(L"Dumbo.Default");
  ASSERT_NO_FATAL_FAILURE(
      AddTestShortcutAndResetProperties(temp_dir_.GetPath(), &temp_properties));
  MigrateTaskbarPinsCallback(temp_dir_.GetPath(), temp_dir_.GetPath());
  // Verify that the shortcut was migrated, i.e., its app_id does not contain
  // the default profile name.
  shortcuts_[0].properties.set_app_id(chrome_app_id_);
  base::win::ValidateShortcut(shortcuts_[0].path, shortcuts_[0].properties);
}

TEST(ShellIntegrationWinTest, GetAppModelIdForProfileTest) {
  const std::wstring base_app_id(install_static::GetBaseAppId());

  // Empty profile path should get chrome::kBrowserAppID
  std::wstring app_name = L"app";
  std::wstring expected_model_id_without_profile =
      base_app_id + L"." + app_name;
  base::FilePath empty_path;
  EXPECT_EQ(expected_model_id_without_profile,
            GetAppUserModelIdForApp(app_name, empty_path));

  // Default profile path should get chrome::kBrowserAppID
  base::FilePath default_user_data_dir;
  chrome::GetDefaultUserDataDirectory(&default_user_data_dir);
  base::FilePath default_profile_path =
      default_user_data_dir.AppendASCII(chrome::kInitialProfile);
  EXPECT_EQ(expected_model_id_without_profile,
            GetAppUserModelIdForApp(app_name, default_profile_path));

  // Non-default profile path should get chrome::kBrowserAppID joined with
  // profile info.
  base::FilePath profile_path(FILE_PATH_LITERAL("root"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("udd"));
  profile_path = profile_path.Append(FILE_PATH_LITERAL("User Data - Test"));
  EXPECT_EQ(expected_model_id_without_profile + L".udd.UserDataTest",
            GetAppUserModelIdForApp(app_name, profile_path));
}

}  // namespace win
}  // namespace shell_integration
