// Copyright (c) 2011 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 "base/bind.h"
#include "base/command_line.h"
#include "base/mac/mac_util.h"
#include "base/prefs/pref_service.h"
#include "chrome/browser/background/background_mode_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

using content::BrowserThread;

namespace {
void SetUserRemovedLoginItemPrefOnUIThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  PrefService* service = g_browser_process->local_state();
  service->SetBoolean(prefs::kUserRemovedLoginItem, true);
}

void SetCreatedLoginItemPrefOnUIThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  PrefService* service = g_browser_process->local_state();
  service->SetBoolean(prefs::kChromeCreatedLoginItem, true);
}

void DisableLaunchOnStartupOnFileThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  // If the LoginItem is not hidden, it means it's user created, so don't
  // delete it.
  bool is_hidden = false;
  if (base::mac::CheckLoginItemStatus(&is_hidden) && is_hidden)
    base::mac::RemoveFromLoginItems();
}

void CheckForUserRemovedLoginItemOnFileThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  if (!base::mac::CheckLoginItemStatus(NULL)) {
    // There's no LoginItem, so set the kUserRemovedLoginItem pref.
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                            base::Bind(SetUserRemovedLoginItemPrefOnUIThread));
  }
}

void EnableLaunchOnStartupOnFileThread(bool need_migration) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
  if (need_migration) {
    // This is the first time running Chrome since the kChromeCreatedLoginItem
    // pref was added. Initialize the status of this pref based on whether
    // there is already a hidden login item.
    bool is_hidden = false;
    if (base::mac::CheckLoginItemStatus(&is_hidden)) {
      if (is_hidden) {
      // We already have a hidden login item, so set the kChromeCreatedLoginItem
      // flag.
        BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                                base::Bind(SetCreatedLoginItemPrefOnUIThread));
      }
      // LoginItem already exists - just exit.
      return;
    }
  }

  // Check if Chrome is already a Login Item - if not, create one.
  if (!base::mac::CheckLoginItemStatus(NULL)) {
    // Call back to the UI thread to set our preference so we know that Chrome
    // created the login item (which means we are allowed to delete it later).
    // There's a race condition here if the user disables launch on startup
    // before our callback is run, but the user can manually disable
    // "Open At Login" via the dock if this happens.
    base::mac::AddToLoginItems(true);  // Hide on startup.
    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
                            base::Bind(SetCreatedLoginItemPrefOnUIThread));
  }
}

}  // namespace

void BackgroundModeManager::EnableLaunchOnStartup(bool should_launch) {
  // LoginItems are associated with an executable, not with a specific
  // user-data-dir, so only mess with the LoginItem when running with the
  // default user-data-dir. So if a user is running multiple instances of
  // Chrome with different user-data-dirs, they won't conflict in their
  // use of LoginItems.
  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUserDataDir))
    return;

  // There are a few cases we need to handle:
  //
  // 1) Chrome is transitioning to "launch on startup" state, and there's no
  // login item currently. We create a new item if the kUserRemovedLoginItem
  // and kChromeCreatedLoginItem flags are already false, and set the
  // kChromeCreatedLoginItem flag to true. If kChromeCreatedLoginItem is
  // already set (meaning that we created a login item that has since been
  // deleted) then we will set the kUserRemovedLoginItem so we do not create
  // login items in the future.
  //
  // 2) Chrome is transitioning to the "do not launch on startup" state. If
  // the kChromeCreatedLoginItem flag is false, we do nothing. Otherwise, we
  // will delete the login item if it's present, and not we will set
  // kUserRemovedLoginItem to true to prevent future login items from being
  // created.
  if (should_launch) {
    PrefService* service = g_browser_process->local_state();
    // If the user removed the login item, don't ever create another one.
    if (service->GetBoolean(prefs::kUserRemovedLoginItem))
      return;

    if (service->GetBoolean(prefs::kChromeCreatedLoginItem)) {
      DCHECK(service->GetBoolean(prefs::kMigratedLoginItemPref));
      // If we previously created a login item, we don't need to create
      // a new one - just check to see if the user removed it so we don't
      // ever create another one.
      BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                              base::Bind(
                                  CheckForUserRemovedLoginItemOnFileThread));
    } else {
      bool need_migration = !service->GetBoolean(
          prefs::kMigratedLoginItemPref);
      service->SetBoolean(prefs::kMigratedLoginItemPref, true);
      BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                              base::Bind(EnableLaunchOnStartupOnFileThread,
                                         need_migration));
    }
  } else {
    PrefService* service = g_browser_process->local_state();
    // If Chrome didn't create any login items, just exit.
    if (!service->GetBoolean(prefs::kChromeCreatedLoginItem))
      return;

    // Clear the pref now that we're removing the login item.
    service->ClearPref(prefs::kChromeCreatedLoginItem);

    // If the user removed our login item, note this so we don't ever create
    // another one.
    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                            base::Bind(
                                CheckForUserRemovedLoginItemOnFileThread));

    // Call to the File thread to remove the login item since it requires
    // accessing the disk.
    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
                            base::Bind(DisableLaunchOnStartupOnFileThread));
  }
}

void BackgroundModeManager::DisplayAppInstalledNotification(
    const extensions::Extension* extension) {
  // TODO(atwilson): Display a platform-appropriate notification here.
  // http://crbug.com/74970
}

base::string16 BackgroundModeManager::GetPreferencesMenuLabel() {
  return l10n_util::GetStringUTF16(IDS_OPTIONS);
}
