// Copyright 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 "base/compiler_specific.h"
#include "base/memory/scoped_vector.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/backend_migrator.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/test/integration/bookmarks_helper.h"
#include "chrome/browser/sync/test/integration/preferences_helper.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/single_client_status_change_checker.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/translate/core/browser/translate_prefs.h"

using bookmarks_helper::AddURL;
using bookmarks_helper::IndexedURL;
using bookmarks_helper::IndexedURLTitle;

using preferences_helper::BooleanPrefMatches;
using preferences_helper::ChangeBooleanPref;

namespace {

// Utility functions to make a model type set out of a small number of
// model types.

syncer::ModelTypeSet MakeSet(syncer::ModelType type) {
  return syncer::ModelTypeSet(type);
}

syncer::ModelTypeSet MakeSet(syncer::ModelType type1,
                             syncer::ModelType type2) {
  return syncer::ModelTypeSet(type1, type2);
}

// An ordered list of model types sets to migrate.  Used by
// RunMigrationTest().
typedef std::deque<syncer::ModelTypeSet> MigrationList;

// Utility functions to make a MigrationList out of a small number of
// model types / model type sets.

MigrationList MakeList(syncer::ModelTypeSet model_types) {
  return MigrationList(1, model_types);
}

MigrationList MakeList(syncer::ModelTypeSet model_types1,
                       syncer::ModelTypeSet model_types2) {
  MigrationList migration_list;
  migration_list.push_back(model_types1);
  migration_list.push_back(model_types2);
  return migration_list;
}

MigrationList MakeList(syncer::ModelType type) {
  return MakeList(MakeSet(type));
}

MigrationList MakeList(syncer::ModelType type1,
                       syncer::ModelType type2) {
  return MakeList(MakeSet(type1), MakeSet(type2));
}

// Helper class that checks if the sync backend has successfully completed
// migration for a set of data types.
class MigrationChecker : public SingleClientStatusChangeChecker,
                         public browser_sync::MigrationObserver {
 public:
  explicit MigrationChecker(ProfileSyncServiceHarness* harness)
      : SingleClientStatusChangeChecker(harness->service()),
        harness_(harness) {
    DCHECK(harness_);
    browser_sync::BackendMigrator* migrator =
        harness_->service()->GetBackendMigratorForTest();
    // PSS must have a migrator after sync is setup and initial data type
    // configuration is complete.
    DCHECK(migrator);
    migrator->AddMigrationObserver(this);
  }

  virtual ~MigrationChecker() {}

  // Returns true when sync reports that there is no pending migration, and
  // migration is complete for all data types in |expected_types_|.
  virtual bool IsExitConditionSatisfied() OVERRIDE {
    DCHECK(!expected_types_.Empty());
    bool all_expected_types_migrated = migrated_types_.HasAll(expected_types_);
    DVLOG(1) << harness_->profile_debug_name() << ": Migrated types "
             << syncer::ModelTypeSetToString(migrated_types_)
             << (all_expected_types_migrated ? " contains " :
                                               " does not contain ")
             << syncer::ModelTypeSetToString(expected_types_);
    return all_expected_types_migrated &&
           !HasPendingBackendMigration();
  }

  virtual std::string GetDebugMessage() const OVERRIDE {
    return "Waiting to migrate (" + ModelTypeSetToString(expected_types_) + ")";
  }

  bool HasPendingBackendMigration() const {
    browser_sync::BackendMigrator* migrator =
        harness_->service()->GetBackendMigratorForTest();
    return migrator && migrator->state() != browser_sync::BackendMigrator::IDLE;
  }

  void set_expected_types(syncer::ModelTypeSet expected_types) {
    expected_types_ = expected_types;
  }

  syncer::ModelTypeSet migrated_types() const {
    return migrated_types_;
  }

  virtual void OnMigrationStateChange() OVERRIDE {
    if (HasPendingBackendMigration()) {
      // A new bunch of data types are in the process of being migrated. Merge
      // them into |pending_types_|.
      pending_types_.PutAll(
          harness_->service()->GetBackendMigratorForTest()->
              GetPendingMigrationTypesForTest());
      DVLOG(1) << harness_->profile_debug_name()
               << ": new pending migration types "
               << syncer::ModelTypeSetToString(pending_types_);
    } else {
      // Migration just finished for a bunch of data types. Merge them into
      // |migrated_types_|.
      migrated_types_.PutAll(pending_types_);
      pending_types_.Clear();
      DVLOG(1) << harness_->profile_debug_name() << ": new migrated types "
               << syncer::ModelTypeSetToString(migrated_types_);
    }

    // Manually trigger a check of the exit condition.
    if (!expected_types_.Empty())
      OnStateChanged();
  }

 private:
  // The sync client for which migration is being verified.
  ProfileSyncServiceHarness* harness_;

  // The set of data types that are expected to eventually undergo migration.
  syncer::ModelTypeSet expected_types_;

  // The set of data types currently undergoing migration.
  syncer::ModelTypeSet pending_types_;

  // The set of data types for which migration is complete. Accumulated by
  // successive calls to OnMigrationStateChanged.
  syncer::ModelTypeSet migrated_types_;

  DISALLOW_COPY_AND_ASSIGN(MigrationChecker);
};

class MigrationTest : public SyncTest  {
 public:
  explicit MigrationTest(TestType test_type) : SyncTest(test_type) {}
  virtual ~MigrationTest() {}

  enum TriggerMethod { MODIFY_PREF, MODIFY_BOOKMARK, TRIGGER_NOTIFICATION };

  // Set up sync for all profiles and initialize all MigrationCheckers. This
  // helps ensure that all migration events are captured, even if they were to
  // occur before a test calls AwaitMigration for a specific profile.
  virtual bool SetupSync() OVERRIDE {
    if (!SyncTest::SetupSync())
      return false;

    for (int i = 0; i < num_clients(); ++i) {
      MigrationChecker* checker = new MigrationChecker(GetClient(i));
      migration_checkers_.push_back(checker);
    }
    return true;
  }

  syncer::ModelTypeSet GetPreferredDataTypes() {
    // ProfileSyncService must already have been created before we can call
    // GetPreferredDataTypes().
    DCHECK(GetSyncService((0)));
    syncer::ModelTypeSet preferred_data_types =
        GetSyncService((0))->GetPreferredDataTypes();
    preferred_data_types.RemoveAll(syncer::ProxyTypes());

    // The managed user settings will be "unready" during this test, so we
    // should not request that they be migrated.
    preferred_data_types.Remove(syncer::SUPERVISED_USER_SETTINGS);

    // Make sure all clients have the same preferred data types.
    for (int i = 1; i < num_clients(); ++i) {
      const syncer::ModelTypeSet other_preferred_data_types =
          GetSyncService((i))->GetPreferredDataTypes();
      EXPECT_TRUE(preferred_data_types.Equals(other_preferred_data_types));
    }
    return preferred_data_types;
  }

  // Returns a MigrationList with every enabled data type in its own
  // set.
  MigrationList GetPreferredDataTypesList() {
    MigrationList migration_list;
    const syncer::ModelTypeSet preferred_data_types =
        GetPreferredDataTypes();
    for (syncer::ModelTypeSet::Iterator it =
             preferred_data_types.First(); it.Good(); it.Inc()) {
      migration_list.push_back(MakeSet(it.Get()));
    }
    return migration_list;
  }

  // Trigger a migration for the given types with the given method.
  void TriggerMigration(syncer::ModelTypeSet model_types,
                        TriggerMethod trigger_method) {
    switch (trigger_method) {
      case MODIFY_PREF:
        // Unlike MODIFY_BOOKMARK, MODIFY_PREF doesn't cause a
        // notification to happen (since model association on a
        // boolean pref clobbers the local value), so it doesn't work
        // for anything but single-client tests.
        ASSERT_EQ(1, num_clients());
        ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
        ChangeBooleanPref(0, prefs::kShowHomeButton);
        break;
      case MODIFY_BOOKMARK:
        ASSERT_TRUE(AddURL(0, IndexedURLTitle(0), GURL(IndexedURL(0))));
        break;
      case TRIGGER_NOTIFICATION:
        TriggerNotification(model_types);
        break;
      default:
        ADD_FAILURE();
    }
  }

  // Block until all clients have completed migration for the given
  // types.
  void AwaitMigration(syncer::ModelTypeSet migrate_types) {
    for (int i = 0; i < num_clients(); ++i) {
      MigrationChecker* checker = migration_checkers_[i];
      checker->set_expected_types(migrate_types);
      checker->Wait();
      ASSERT_FALSE(checker->TimedOut());
    }
  }

  // Makes sure migration works with the given migration list and
  // trigger method.
  void RunMigrationTest(const MigrationList& migration_list,
                        TriggerMethod trigger_method) {
    // If we have only one client, turn off notifications to avoid the
    // possibility of spurious sync cycles.
    bool do_test_without_notifications =
        (trigger_method != TRIGGER_NOTIFICATION && num_clients() == 1);

    if (do_test_without_notifications) {
      DisableNotifications();
    }

    // Make sure migration hasn't been triggered prematurely.
    for (int i = 0; i < num_clients(); ++i) {
      ASSERT_TRUE(migration_checkers_[i]->migrated_types().Empty());
    }

    // Phase 1: Trigger the migrations on the server.
    for (MigrationList::const_iterator it = migration_list.begin();
         it != migration_list.end(); ++it) {
      TriggerMigrationDoneError(*it);
    }

    // Phase 2: Trigger each migration individually and wait for it to
    // complete.  (Multiple migrations may be handled by each
    // migration cycle, but there's no guarantee of that, so we have
    // to trigger each migration individually.)
    for (MigrationList::const_iterator it = migration_list.begin();
         it != migration_list.end(); ++it) {
      TriggerMigration(*it, trigger_method);
      AwaitMigration(*it);
    }

    // Phase 3: Wait for all clients to catch up.
    //
    // AwaitQuiescence() will not succeed when notifications are disabled.  We
    // can safely avoid calling it because we know that, in the single client
    // case, there is no one else to wait for.
    //
    // TODO(rlarocque, 97780): Remove the if condition when the test harness
    // supports calling AwaitQuiescence() when notifications are disabled.
    if (!do_test_without_notifications) {
      AwaitQuiescence();
    }

    // TODO(rlarocque): It should be possible to re-enable notifications
    // here, but doing so makes some windows tests flaky.
  }

 private:
  // Used to keep track of the migration progress for each sync client.
  ScopedVector<MigrationChecker> migration_checkers_;

  DISALLOW_COPY_AND_ASSIGN(MigrationTest);
};

class MigrationSingleClientTest : public MigrationTest {
 public:
  MigrationSingleClientTest() : MigrationTest(SINGLE_CLIENT_LEGACY) {}
  virtual ~MigrationSingleClientTest() {}

  void RunSingleClientMigrationTest(const MigrationList& migration_list,
                                    TriggerMethod trigger_method) {
    ASSERT_TRUE(SetupSync());
    RunMigrationTest(migration_list, trigger_method);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MigrationSingleClientTest);
};

// The simplest possible migration tests -- a single data type.

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyPref) {
  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES), MODIFY_PREF);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsOnlyModifyBookmark) {
  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
                               MODIFY_BOOKMARK);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
                       PrefsOnlyTriggerNotification) {
  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
                               TRIGGER_NOTIFICATION);
}

// Nigori is handled specially, so we test that separately.

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, NigoriOnly) {
  RunSingleClientMigrationTest(MakeList(syncer::PREFERENCES),
                               TRIGGER_NOTIFICATION);
}

// A little more complicated -- two data types.

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, BookmarksPrefsIndividually) {
  RunSingleClientMigrationTest(
      MakeList(syncer::BOOKMARKS, syncer::PREFERENCES),
      MODIFY_PREF);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, BookmarksPrefsBoth) {
  RunSingleClientMigrationTest(
      MakeList(MakeSet(syncer::BOOKMARKS, syncer::PREFERENCES)),
      MODIFY_BOOKMARK);
}

// Two data types with one being nigori.

// See crbug.com/124480.
IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
                       DISABLED_PrefsNigoriIndividiaully) {
  RunSingleClientMigrationTest(
      MakeList(syncer::PREFERENCES, syncer::NIGORI),
      TRIGGER_NOTIFICATION);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, PrefsNigoriBoth) {
  RunSingleClientMigrationTest(
      MakeList(MakeSet(syncer::PREFERENCES, syncer::NIGORI)),
      MODIFY_PREF);
}

// The whole shebang -- all data types.
#if defined(OS_WIN)
// http://crbug.com/403778
#define MAYBE_AllTypesIndividually DISABLED_AllTypesIndividually
#else
#define MAYBE_AllTypesIndividually AllTypesIndividually
#endif
IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, MAYBE_AllTypesIndividually) {
  ASSERT_TRUE(SetupClients());
  RunSingleClientMigrationTest(GetPreferredDataTypesList(), MODIFY_BOOKMARK);
}

#if defined(OS_WIN)
// http://crbug.com/403778
#define MAYBE_AllTypesIndividuallyTriggerNotification DISABLED_AllTypesIndividuallyTriggerNotification
#else
#define MAYBE_AllTypesIndividuallyTriggerNotification AllTypesIndividuallyTriggerNotification
#endif
IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
                       MAYBE_AllTypesIndividuallyTriggerNotification) {
  ASSERT_TRUE(SetupClients());
  RunSingleClientMigrationTest(GetPreferredDataTypesList(),
                               TRIGGER_NOTIFICATION);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesAtOnce) {
  ASSERT_TRUE(SetupClients());
  RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
                               MODIFY_PREF);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
                       AllTypesAtOnceTriggerNotification) {
  ASSERT_TRUE(SetupClients());
  RunSingleClientMigrationTest(MakeList(GetPreferredDataTypes()),
                               TRIGGER_NOTIFICATION);
}

// All data types plus nigori.

// See crbug.com/124480.
IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest,
                       DISABLED_AllTypesWithNigoriIndividually) {
  ASSERT_TRUE(SetupClients());
  MigrationList migration_list = GetPreferredDataTypesList();
  migration_list.push_front(MakeSet(syncer::NIGORI));
  RunSingleClientMigrationTest(migration_list, MODIFY_BOOKMARK);
}

IN_PROC_BROWSER_TEST_F(MigrationSingleClientTest, AllTypesWithNigoriAtOnce) {
  ASSERT_TRUE(SetupClients());
  syncer::ModelTypeSet all_types = GetPreferredDataTypes();
  all_types.Put(syncer::NIGORI);
  RunSingleClientMigrationTest(MakeList(all_types), MODIFY_PREF);
}

class MigrationTwoClientTest : public MigrationTest {
 public:
  MigrationTwoClientTest() : MigrationTest(TWO_CLIENT_LEGACY) {}
  virtual ~MigrationTwoClientTest() {}

  // Helper function that verifies that preferences sync still works.
  void VerifyPrefSync() {
    ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
    ChangeBooleanPref(0, prefs::kShowHomeButton);
    ASSERT_TRUE(GetClient(0)->AwaitMutualSyncCycleCompletion(GetClient(1)));
    ASSERT_TRUE(BooleanPrefMatches(prefs::kShowHomeButton));
  }

  void RunTwoClientMigrationTest(const MigrationList& migration_list,
                                 TriggerMethod trigger_method) {
    ASSERT_TRUE(SetupSync());

    // Make sure pref sync works before running the migration test.
    VerifyPrefSync();

    RunMigrationTest(migration_list, trigger_method);

    // Make sure pref sync still works after running the migration
    // test.
    VerifyPrefSync();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MigrationTwoClientTest);
};

// Easiest possible test of migration errors: triggers a server
// migration on one datatype, then modifies some other datatype.
IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest, MigratePrefsThenModifyBookmark) {
  RunTwoClientMigrationTest(MakeList(syncer::PREFERENCES),
                            MODIFY_BOOKMARK);
}

// Triggers a server migration on two datatypes, then makes a local
// modification to one of them.
IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
                       MigratePrefsAndBookmarksThenModifyBookmark) {
  RunTwoClientMigrationTest(
      MakeList(syncer::PREFERENCES, syncer::BOOKMARKS),
      MODIFY_BOOKMARK);
}

// Migrate every datatype in sequence; the catch being that the server
// will only tell the client about the migrations one at a time.
// TODO(rsimha): This test takes longer than 60 seconds, and will cause tree
// redness due to sharding.
// Re-enable this test after syncer::kInitialBackoffShortRetrySeconds is reduced
// to zero.
IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
                       DISABLED_MigrationHellWithoutNigori) {
  ASSERT_TRUE(SetupClients());
  MigrationList migration_list = GetPreferredDataTypesList();
  // Let the first nudge be a datatype that's neither prefs nor
  // bookmarks.
  migration_list.push_front(MakeSet(syncer::THEMES));
  RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
}

// See crbug.com/124480.
IN_PROC_BROWSER_TEST_F(MigrationTwoClientTest,
                       DISABLED_MigrationHellWithNigori) {
  ASSERT_TRUE(SetupClients());
  MigrationList migration_list = GetPreferredDataTypesList();
  // Let the first nudge be a datatype that's neither prefs nor
  // bookmarks.
  migration_list.push_front(MakeSet(syncer::THEMES));
  // Pop off one so that we don't migrate all data types; the syncer
  // freaks out if we do that (see http://crbug.com/94882).
  ASSERT_GE(migration_list.size(), 2u);
  ASSERT_FALSE(migration_list.back().Equals(MakeSet(syncer::NIGORI)));
  migration_list.back() = MakeSet(syncer::NIGORI);
  RunTwoClientMigrationTest(migration_list, MODIFY_BOOKMARK);
}

class MigrationReconfigureTest : public MigrationTwoClientTest {
 public:
  MigrationReconfigureTest() {}

  virtual void SetUpCommandLine(base::CommandLine* cl) OVERRIDE {
    AddTestSwitches(cl);
    // Do not add optional datatypes.
  }

  virtual ~MigrationReconfigureTest() {}

 private:
  DISALLOW_COPY_AND_ASSIGN(MigrationReconfigureTest);
};

}  // namespace
