// Copyright 2013 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/apps/shortcut_manager.h"

#include "base/bind.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/ui/web_applications/web_app_ui.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"

#if defined(OS_MACOSX)
#include "apps/app_shim/app_shim_mac.h"
#endif

using extensions::Extension;

namespace {

// Creates a shortcut for an application in the applications menu, if there is
// not already one present.
void CreateShortcutsInApplicationsMenu(
    const ShellIntegration::ShortcutInfo& shortcut_info) {
  ShellIntegration::ShortcutLocations creation_locations;
  // Create the shortcut in the Chrome Apps subdir.
  creation_locations.applications_menu_location =
      ShellIntegration::APP_MENU_LOCATION_SUBDIR_CHROMEAPPS;
  web_app::CreateShortcuts(shortcut_info, creation_locations,
                           web_app::SHORTCUT_CREATION_AUTOMATED);
}

bool ShouldCreateShortcutFor(const extensions::Extension* extension) {
  return extension->is_platform_app() &&
      extension->location() != extensions::Manifest::COMPONENT &&
      extension->ShouldDisplayInAppLauncher();
}

}  // namespace

// static
void AppShortcutManager::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  // Indicates whether app shortcuts have been created.
  registry->RegisterBooleanPref(
      prefs::kAppShortcutsHaveBeenCreated, false,
      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}

AppShortcutManager::AppShortcutManager(Profile* profile)
    : profile_(profile),
      is_profile_info_cache_observer_(false),
      prefs_(profile->GetPrefs()),
      weak_factory_(this) {
  // Use of g_browser_process requires that we are either on the UI thread, or
  // there are no threads initialized (such as in unit tests).
  DCHECK(!content::BrowserThread::IsThreadInitialized(
             content::BrowserThread::UI) ||
         content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
                 content::Source<Profile>(profile_));
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
                 content::Source<Profile>(profile_));
  // Wait for extensions to be ready before running OnceOffCreateShortcuts.
  registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
                 content::Source<Profile>(profile_));

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  // profile_manager might be NULL in testing environments.
  if (profile_manager) {
    profile_manager->GetProfileInfoCache().AddObserver(this);
    is_profile_info_cache_observer_ = true;
  }
}

AppShortcutManager::~AppShortcutManager() {
  if (g_browser_process && is_profile_info_cache_observer_) {
    ProfileManager* profile_manager = g_browser_process->profile_manager();
    // profile_manager might be NULL in testing environments or during shutdown.
    if (profile_manager)
      profile_manager->GetProfileInfoCache().RemoveObserver(this);
  }
}

void AppShortcutManager::Observe(int type,
                                 const content::NotificationSource& source,
                                 const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_EXTENSIONS_READY: {
      OnceOffCreateShortcuts();
      break;
    }
    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
#if defined(OS_MACOSX)
      if (!apps::IsAppShimsEnabled())
        break;
#endif  // defined(OS_MACOSX)

      const extensions::InstalledExtensionInfo* installed_info =
          content::Details<const extensions::InstalledExtensionInfo>(details)
              .ptr();
      const Extension* extension = installed_info->extension;
      if (ShouldCreateShortcutFor(extension)) {
        // If the app is being updated, update any existing shortcuts but do not
        // create new ones. If it is being installed, automatically create a
        // shortcut in the applications menu (e.g., Start Menu).
        base::Callback<void(const ShellIntegration::ShortcutInfo&)>
            create_or_update;
        if (installed_info->is_update) {
          base::string16 old_title = UTF8ToUTF16(installed_info->old_name);
          create_or_update = base::Bind(&web_app::UpdateAllShortcuts,
                                        old_title);
        } else {
          create_or_update = base::Bind(&CreateShortcutsInApplicationsMenu);
        }

        web_app::UpdateShortcutInfoAndIconForApp(*extension, profile_,
                                                 create_or_update);
      }
      break;
    }
    case chrome::NOTIFICATION_EXTENSION_UNINSTALLED: {
      const Extension* extension = content::Details<const Extension>(
          details).ptr();
      DeleteApplicationShortcuts(extension);
      break;
    }
    default:
      NOTREACHED();
  }
}

void AppShortcutManager::OnProfileWillBeRemoved(
    const base::FilePath& profile_path) {
  if (profile_path != profile_->GetPath())
    return;
  content::BrowserThread::PostTask(
      content::BrowserThread::FILE, FROM_HERE,
      base::Bind(&web_app::internals::DeleteAllShortcutsForProfile,
                 profile_path));
}

void AppShortcutManager::OnceOffCreateShortcuts() {
  bool was_enabled = prefs_->GetBoolean(prefs::kAppShortcutsHaveBeenCreated);

  // Creation of shortcuts on Mac currently sits behind --enable-app-shims.
  // Until it is enabled permanently, we need to check the flag, and set the
  // pref accordingly.
#if defined(OS_MACOSX)
  bool is_now_enabled = apps::IsAppShimsEnabled();
#else
  bool is_now_enabled = true;
#endif  // defined(OS_MACOSX)

  if (was_enabled != is_now_enabled)
    prefs_->SetBoolean(prefs::kAppShortcutsHaveBeenCreated, is_now_enabled);

  if (was_enabled || !is_now_enabled)
    return;

  // Check if extension system/service are available. They might not be in
  // tests.
  extensions::ExtensionSystem* extension_system;
  ExtensionServiceInterface* extension_service;
  if (!(extension_system = extensions::ExtensionSystem::Get(profile_)) ||
      !(extension_service = extension_system->extension_service()))
    return;

  // Create an applications menu shortcut for each app in this profile.
  const ExtensionSet* apps = extension_service->extensions();
  for (ExtensionSet::const_iterator it = apps->begin();
       it != apps->end(); ++it) {
    if (ShouldCreateShortcutFor(it->get()))
      web_app::UpdateShortcutInfoAndIconForApp(
          *it->get(), profile_, base::Bind(&CreateShortcutsInApplicationsMenu));
  }
}

void AppShortcutManager::DeleteApplicationShortcuts(
    const Extension* extension) {
  ShellIntegration::ShortcutInfo delete_info =
      web_app::ShortcutInfoForExtensionAndProfile(extension, profile_);
  web_app::DeleteAllShortcuts(delete_info);
}
