// Copyright 2014 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/command_line.h"
#include "base/message_loop/message_loop.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/test/integration/bookmarks_helper.h"
#include "chrome/browser/sync/test/integration/sync_integration_test_util.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "chrome/common/chrome_switches.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "sync/test/fake_server/fake_server_verifier.h"

using bookmarks_helper::AddFolder;
using bookmarks_helper::AddURL;
using bookmarks_helper::GetOtherNode;
using bookmarks_helper::ModelMatchesVerifier;
using bookmarks_helper::Move;
using bookmarks_helper::Remove;
using sync_integration_test_util::AwaitCommitActivityCompletion;

class SingleClientBackupRollbackTest : public SyncTest {
 public:
  SingleClientBackupRollbackTest() : SyncTest(SINGLE_CLIENT) {}
  virtual ~SingleClientBackupRollbackTest() {}

  virtual void SetUp() OVERRIDE {
    CommandLine::ForCurrentProcess()->AppendSwitch(
          switches::kSyncEnableRollback);
    SyncTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(SingleClientBackupRollbackTest);
};

class BackupModeChecker {
 public:
  explicit BackupModeChecker(ProfileSyncService* service,
                             base::TimeDelta timeout)
      : pss_(service),
        expiration_(base::TimeTicks::Now() + timeout) {}

  bool Wait() {
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
        base::TimeDelta::FromSeconds(1));
    base::MessageLoop::current()->Run();
    return IsBackupComplete();
  }

 private:
  void PeriodicCheck() {
    if (IsBackupComplete() || base::TimeTicks::Now() > expiration_) {
      base::MessageLoop::current()->Quit();
    } else {
      base::MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          base::Bind(&BackupModeChecker::PeriodicCheck, base::Unretained(this)),
          base::TimeDelta::FromSeconds(1));
    }
  }

  bool IsBackupComplete() {
    return pss_->backend_mode() == ProfileSyncService::BACKUP &&
        pss_->ShouldPushChanges();
  }

  ProfileSyncService* pss_;
  base::TimeTicks expiration_;
};

#if defined(ENABLE_PRE_SYNC_BACKUP)
#define MAYBE_TestBackupRollback TestBackupRollback
#else
#define MAYBE_TestBackupRollback DISABLED_TestBackupRollback
#endif
IN_PROC_BROWSER_TEST_F(SingleClientBackupRollbackTest,
                       MAYBE_TestBackupRollback) {
  ASSERT_TRUE(SetupClients()) << "SetupClients() failed.";

  // Starting state:
  // other_node
  //    -> top
  //      -> tier1_a
  //        -> http://mail.google.com  "tier1_a_url0"
  //      -> tier1_b
  //        -> http://www.nhl.com "tier1_b_url0"
  const BookmarkNode* top = AddFolder(0, GetOtherNode(0), 0, "top");
  const BookmarkNode* tier1_a = AddFolder(0, top, 0, "tier1_a");
  const BookmarkNode* tier1_b = AddFolder(0, top, 1, "tier1_b");
  ASSERT_TRUE(AddURL(0, tier1_a, 0, "tier1_a_url0",
                     GURL("http://mail.google.com")));
  ASSERT_TRUE(AddURL(0, tier1_b, 0, "tier1_b_url0",
                     GURL("http://www.nhl.com")));

  BackupModeChecker checker(GetSyncService(0),
                            base::TimeDelta::FromSeconds(15));
  ASSERT_TRUE(checker.Wait());

  // Setup sync, wait for its completion, and make sure changes were synced.
  ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
  ASSERT_TRUE(ModelMatchesVerifier(0));

  // Made bookmark changes while sync is on.
  Move(0, tier1_a->GetChild(0), tier1_b, 1);
  Remove(0, tier1_b, 0);
  ASSERT_TRUE(AddFolder(0, tier1_b, 1, "tier2_c"));
  ASSERT_TRUE(AwaitCommitActivityCompletion(GetSyncService((0))));
  ASSERT_TRUE(ModelMatchesVerifier(0));

  // Let server to return rollback command on next sync request.
  GetFakeServer()->TriggerError(sync_pb::SyncEnums::USER_ROLLBACK);

  // Make another change to trigger downloading of rollback command.
  Remove(0, tier1_b, 0);

  // Wait for sync to switch to backup mode after finishing rollback.
  ASSERT_TRUE(checker.Wait());

  // Verify bookmarks are restored.
  ASSERT_EQ(1, tier1_a->child_count());
  const BookmarkNode* url1 = tier1_a->GetChild(0);
  ASSERT_EQ(GURL("http://mail.google.com"), url1->url());

  ASSERT_EQ(1, tier1_b->child_count());
  const BookmarkNode* url2 = tier1_b->GetChild(0);
  ASSERT_EQ(GURL("http://www.nhl.com"), url2->url());
}
