nsresult
sbWatchFolderService::OnAppStartup()
{
  nsresult rv = SetStartupDelayTimer();
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
NS_IMETHODIMP
sbWatchFolder::Start(const nsACString & aSessionGuid)
{
  mFileSystemWatcherGUID = aSessionGuid;

  nsresult rv = SetStartupDelayTimer();
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
nsresult
sbWatchFolderService::OnEnableWatchFolderChanged(bool aShouldEnable)
{
  LOG(("%s: OnEnableWatchFolderChanged( aShouldEnable=%s )",
        __FUNCTION__,
        (aShouldEnable ? "true" : "false")));

  nsresult rv;

  // Stop watching since the service is watching and the pref was toggled
  // to not watch.
  if (mServiceState == eWatching && !aShouldEnable) {
    rv = StopWatchingFolder();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Start watching since the service is not watching and the pref was
  // toggled to start watching.
  else if (mServiceState == eStarted && aShouldEnable) {
    rv = StartWatchingFolder();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // The service has not yet attempted to start up and was just turned on.
  // Start the timer if the service is in a disabled state, the watch path
  // has been defined, and the service should enable.
  else if (mServiceState == eDisabled &&
           !mWatchPath.IsEmpty() &&
           aShouldEnable)
  {
    rv = SetStartupDelayTimer();
    NS_ENSURE_SUCCESS(rv, rv);
  }

  return NS_OK;
}
nsresult
sbWatchFolderService::OnWatchFolderPathChanged(const nsAString & aNewWatchPath)
{
  LOG(("%s: OnWatchFolderPathChanged( %s )",
        __FUNCTION__,
        NS_ConvertUTF16toUTF8(aNewWatchPath).get()));

  if (mWatchPath.Equals(aNewWatchPath)) {
    return NS_OK;
  }

  nsresult rv;
  nsCOMPtr<nsIPrefBranch2> prefBranch =
      do_GetService("@mozilla.org/preferences-service;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  mWatchPath = aNewWatchPath;

  if (mServiceState == eWatching) {
    TRACE(("%s: already watching, stopping...", __FUNCTION__));
    NS_ENSURE_STATE(mFileSystemWatcher);

    // The service is currently running with a file system watcher
    // that is currently active. The watcher needs to be stopped (
    // without saving a session) and re-started once it has
    // successfully shutdown.

    // Remove the pref since the watch folder service does not want
    // to load the old session.
    bool hasSavedSessionGUID;
    rv = prefBranch->PrefHasUserValue(PREF_WATCHFOLDER_SESSIONGUID,
                                      &hasSavedSessionGUID);
    NS_ENSURE_SUCCESS(rv, rv);

    if (hasSavedSessionGUID) {
      rv = prefBranch->ClearUserPref(PREF_WATCHFOLDER_SESSIONGUID);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    if (!mFileSystemWatcherGUID.IsEmpty()) {
      // Clear any previously stored data from the session that might
      // be stored in the users profile.
      rv = mFileSystemWatcher->DeleteSession(mFileSystemWatcherGUID);
      if (NS_FAILED(rv)) {
        // Just warn if deleting the previous session fails.
        NS_WARNING("Could not delete old session data!");
      }

      mFileSystemWatcherGUID.Truncate();
    }

    // Set a flag to re-setup a file system watcher once the current
    // one has shutdown.
    mShouldReinitWatcher = PR_TRUE;

    // The service is no longer watching
    mServiceState = eStarted;

    // Flush all event paths, reset flags, and stop the watcher.
    mAddedPaths.clear();
    mRemovedPaths.clear();
    mChangedPaths.clear();
    mDelayedChangedPaths.clear();

    rv = mFileSystemWatcher->StopWatching(PR_FALSE);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  else if (mServiceState == eDisabled && !mWatchPath.IsEmpty()) {
    // The service has not started up internally, but the watch path
    // has changed. If the service has been set to be enabled, start
    // the delayed internal startup.
    bool shouldEnable = PR_FALSE;
    rv = prefBranch->GetBoolPref(PREF_WATCHFOLDER_ENABLE,
        &shouldEnable);
    if (NS_SUCCEEDED(rv) && shouldEnable) {
      TRACE(("%s: not watching yet, arming...", __FUNCTION__));
      // Now that the service state is disabled, the watch path has
      // been set, and the service should enable - it is time to
      // start the delayed internal init.
      rv = SetStartupDelayTimer();
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  return NS_OK;
}