// Copyright (c) 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 <memory>

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/values.h"
#include "chrome/browser/sync/test/integration/bookmarks_helper.h"
#include "chrome/browser/sync/test/integration/profile_sync_service_harness.h"
#include "chrome/browser/sync/test/integration/sync_test.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/test/fake_server/bookmark_entity_builder.h"
#include "components/sync/test/fake_server/entity_builder_factory.h"

using base::FeatureList;
using syncer::ModelType;
using syncer::ModelTypeSet;
using syncer::ModelTypeFromString;
using syncer::ModelTypeToString;
using syncer::ProxyTypes;
using syncer::SyncPrefs;
using syncer::UserSelectableTypes;

namespace {

const char kSyncedBookmarkURL[] = "http://www.mybookmark.com";

// Some types show up in multiple groups. This means that there are at least two
// user selectable groups that will cause these types to become enabled. This
// affects our tests because we cannot assume that before enabling a multi type
// it will be disabled, because the other selectable type(s) could already be
// enabling it. And vice versa for disabling.
ModelTypeSet MultiGroupTypes(const ModelTypeSet& registered_types) {
  const ModelTypeSet selectable_types = UserSelectableTypes();
  ModelTypeSet seen;
  ModelTypeSet multi;
  // TODO(vitaliii): Do not use such short variable names here (and possibly
  // elsewhere in the file).
  for (ModelType st : selectable_types) {
    const ModelTypeSet grouped_types =
        SyncPrefs::ResolvePrefGroups(registered_types, ModelTypeSet(st));
    for (ModelType gt : grouped_types) {
      if (seen.Has(gt)) {
        multi.Put(gt);
      } else {
        seen.Put(gt);
      }
    }
  }
  return multi;
}

// This test enables and disables types and verifies the type is sufficiently
// affected by checking for existence of a root node.
class EnableDisableSingleClientTest : public SyncTest {
 public:
  EnableDisableSingleClientTest() : SyncTest(SINGLE_CLIENT) {}
  ~EnableDisableSingleClientTest() override {}

  // Don't use self-notifications as they can trigger additional sync cycles.
  bool TestUsesSelfNotifications() override { return false; }

  bool ModelTypeExists(ModelType type) {
    base::RunLoop loop;
    std::unique_ptr<base::ListValue> all_nodes;
    GetSyncService(0)->GetAllNodes(
        base::BindLambdaForTesting([&](std::unique_ptr<base::ListValue> nodes) {
          all_nodes = std::move(nodes);
          loop.Quit();
        }));
    loop.Run();
    // Look for the root node corresponding to |type|.
    for (const base::Value& value : all_nodes->GetList()) {
      DCHECK(value.is_dict());
      const base::Value* nodes = value.FindKey("nodes");
      DCHECK(nodes);
      DCHECK(nodes->is_list());
      // Ignore types that are empty, because we expect the root node.
      if (nodes->GetList().empty()) {
        continue;
      }
      const base::Value* model_type = value.FindKey("type");
      DCHECK(model_type);
      DCHECK(model_type->is_string());
      if (type == ModelTypeFromString(model_type->GetString())) {
        return true;
      }
    }
    return false;
  }

  void InjectSyncedBookmark() {
    fake_server::BookmarkEntityBuilder bookmark_builder =
        entity_builder_factory_.NewBookmarkEntityBuilder("My Bookmark");
    GetFakeServer()->InjectEntity(
        bookmark_builder.BuildBookmark(GURL(kSyncedBookmarkURL)));
  }

  int GetNumUpdatesDownloadedInLastCycle() {
    return GetSyncService(0)
        ->GetLastCycleSnapshot()
        .model_neutral_state()
        .num_updates_downloaded_total;
  }

 protected:
  void SetupTest(bool all_types_enabled) {
    ASSERT_TRUE(SetupClients());
    if (all_types_enabled) {
      ASSERT_TRUE(GetClient(0)->SetupSync());
    } else {
      ASSERT_TRUE(GetClient(0)->SetupSync(ModelTypeSet()));
    }

    registered_types_ = GetSyncService(0)->GetRegisteredDataTypes();
    selectable_types_ = UserSelectableTypes();
    multi_grouped_types_ = MultiGroupTypes(registered_types_);
  }

  ModelTypeSet ResolveGroup(ModelType type) {
    return Difference(
        SyncPrefs::ResolvePrefGroups(registered_types_, ModelTypeSet(type)),
        ProxyTypes());
  }

  ModelTypeSet WithoutMultiTypes(const ModelTypeSet& input) {
    return Difference(input, multi_grouped_types_);
  }

  ModelTypeSet registered_types_;
  ModelTypeSet selectable_types_;
  ModelTypeSet multi_grouped_types_;

 private:
  fake_server::EntityBuilderFactory entity_builder_factory_;

  DISALLOW_COPY_AND_ASSIGN(EnableDisableSingleClientTest);
};

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableOneAtATime) {
  // Setup sync with no enabled types.
  SetupTest(/*all_types_enabled=*/false);

  for (ModelType st : selectable_types_) {
    const ModelTypeSet grouped_types = ResolveGroup(st);
    const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types);
    for (ModelType sgt : single_grouped_types) {
      ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }

    EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st));

    for (ModelType gt : grouped_types) {
      EXPECT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st);
    }
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, DisableOneAtATime) {
  // Setup sync with no disabled types.
  SetupTest(/*all_types_enabled=*/true);

  for (ModelType st : selectable_types_) {
    const ModelTypeSet grouped_types = ResolveGroup(st);
    for (ModelType gt : grouped_types) {
      ASSERT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st);
    }

    EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st));

    const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types);
    for (ModelType sgt : single_grouped_types) {
      EXPECT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }
  }

  // Lastly make sure that all the multi grouped times are all gone, since we
  // did not check these after disabling inside the above loop.
  for (ModelType mgt : multi_grouped_types_) {
    EXPECT_FALSE(ModelTypeExists(mgt)) << " for " << ModelTypeToString(mgt);
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
                       FastEnableDisableOneAtATime) {
  // Setup sync with no enabled types.
  SetupTest(/*all_types_enabled=*/false);

  for (ModelType st : selectable_types_) {
    const ModelTypeSet grouped_types = ResolveGroup(st);
    const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types);
    for (ModelType sgt : single_grouped_types) {
      ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }

    // Enable and then disable immediately afterwards, before the datatype has
    // had the chance to finish startup (which usually involves task posting).
    EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st));
    EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st));

    for (ModelType sgt : single_grouped_types) {
      EXPECT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }
  }

  // Lastly make sure that all the multi grouped times are all gone, since we
  // did not check these after disabling inside the above loop.
  for (ModelType mgt : multi_grouped_types_) {
    EXPECT_FALSE(ModelTypeExists(mgt)) << " for " << ModelTypeToString(mgt);
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
                       FastDisableEnableOneAtATime) {
  // Setup sync with no disabled types.
  SetupTest(/*all_types_enabled=*/true);

  for (ModelType st : selectable_types_) {
    const ModelTypeSet grouped_types = ResolveGroup(st);
    for (ModelType gt : grouped_types) {
      ASSERT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st);
    }

    // Disable and then reenable immediately afterwards, before the datatype has
    // had the chance to stop fully (which usually involves task posting).
    EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st));
    EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st));

    for (ModelType gt : grouped_types) {
      EXPECT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st);
    }
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
                       FastEnableDisableEnableOneAtATime) {
  // Setup sync with no enabled types.
  SetupTest(/*all_types_enabled=*/false);

  for (ModelType st : selectable_types_) {
    const ModelTypeSet grouped_types = ResolveGroup(st);
    const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types);
    for (ModelType sgt : single_grouped_types) {
      ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }

    // Fast enable-disable-enable sequence, before the datatype has had the
    // chance to transition fully across states (usually involves task posting).
    EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st));
    EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st));
    EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st));

    for (ModelType sgt : single_grouped_types) {
      EXPECT_TRUE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st);
    }
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableDisable) {
  SetupTest(/*all_types_enabled=*/false);

  // Enable all, and then disable immediately afterwards, before datatypes
  // have had the chance to finish startup (which usually involves task
  // posting).
  GetClient(0)->EnableSyncForAllDatatypes();
  GetClient(0)->DisableSyncForAllDatatypes();

  for (ModelType st : selectable_types_) {
    EXPECT_FALSE(ModelTypeExists(st)) << " for " << ModelTypeToString(st);
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, PRE_EnableAndRestart) {
  SetupTest(/*all_types_enabled=*/true);
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, EnableAndRestart) {
  ASSERT_TRUE(SetupClients());

  EXPECT_TRUE(GetClient(0)->AwaitEngineInitialization());

  // Proxy types don't really run.
  const ModelTypeSet non_proxy_types =
      Difference(selectable_types_, ProxyTypes());

  for (ModelType type : non_proxy_types) {
    EXPECT_TRUE(ModelTypeExists(type)) << " for " << ModelTypeToString(type);
  }
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest, FastEnableDisableEnable) {
  SetupTest(/*all_types_enabled=*/false);

  // Enable all, and then disable+reenable immediately afterwards, before
  // datatypes have had the chance to finish startup (which usually involves
  // task posting).
  GetClient(0)->EnableSyncForAllDatatypes();
  GetClient(0)->DisableSyncForAllDatatypes();
  GetClient(0)->EnableSyncForAllDatatypes();

  // Proxy types don't really run.
  const ModelTypeSet non_proxy_types =
      Difference(selectable_types_, ProxyTypes());

  for (ModelType type : non_proxy_types) {
    EXPECT_TRUE(ModelTypeExists(type)) << " for " << ModelTypeToString(type);
  }
}

// This test makes sure that after a RequestStop(CLEAR_DATA), Sync data gets
// redownloaded when Sync is started again. This does not actually verify that
// the data is gone from disk (which seems infeasible); it's mostly here as a
// baseline for the following tests.
IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
                       RedownloadsAfterClearData) {
  ASSERT_TRUE(SetupClients());
  ASSERT_FALSE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));

  // Create a bookmark on the server, then turn on Sync on the client.
  InjectSyncedBookmark();
  ASSERT_TRUE(GetClient(0)->SetupSync());
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // Make sure the bookmark got synced down.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  // Note: The response may also contain permanent nodes, so we can't check the
  // exact count.
  const int initial_updates_downloaded = GetNumUpdatesDownloadedInLastCycle();
  ASSERT_GT(initial_updates_downloaded, 0);

  // Stop and restart Sync.
  GetClient(0)->StopSyncServiceAndClearData();
  GetClient(0)->StartSyncService();
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // Everything should have been redownloaded.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  EXPECT_EQ(GetNumUpdatesDownloadedInLastCycle(), initial_updates_downloaded);
}

IN_PROC_BROWSER_TEST_F(EnableDisableSingleClientTest,
                       DoesNotRedownloadAfterKeepData) {
  ASSERT_TRUE(SetupClients());
  ASSERT_FALSE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));

  // Create a bookmark on the server, then turn on Sync on the client.
  InjectSyncedBookmark();
  ASSERT_TRUE(GetClient(0)->SetupSync());
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // Make sure the bookmark got synced down.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  // Note: The response may also contain permanent nodes, so we can't check the
  // exact count.
  ASSERT_GT(GetNumUpdatesDownloadedInLastCycle(), 0);

  // Stop and restart Sync.
  GetClient(0)->StopSyncServiceWithoutClearingData();
  GetClient(0)->StartSyncService();
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // The bookmark should still be there, *without* having been redownloaded.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  EXPECT_EQ(0, GetNumUpdatesDownloadedInLastCycle());
}

#if defined(THREAD_SANITIZER)
// https://crbug.com/915219
#define MAYBE_DoesNotRedownloadAfterKeepDataWithStandaloneTransport \
  DISABLEDDoesNotRedownloadAfterKeepDataWithStandaloneTransport
#else
#define MAYBE_DoesNotRedownloadAfterKeepDataWithStandaloneTransport \
  DoesNotRedownloadAfterKeepDataWithStandaloneTransport
#endif

IN_PROC_BROWSER_TEST_F(
    EnableDisableSingleClientTest,
    MAYBE_DoesNotRedownloadAfterKeepDataWithStandaloneTransport) {
  base::test::ScopedFeatureList enable_standalone_transport;
  enable_standalone_transport.InitAndEnableFeature(
      switches::kSyncStandaloneTransport);

  ASSERT_TRUE(SetupClients());
  ASSERT_FALSE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));

  // Create a bookmark on the server, then turn on Sync on the client.
  InjectSyncedBookmark();
  ASSERT_TRUE(GetClient(0)->SetupSync());
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // Make sure the bookmark got synced down.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  // Note: The response may also contain permanent nodes, so we can't check the
  // exact count.
  ASSERT_GT(GetNumUpdatesDownloadedInLastCycle(), 0);

  // Stop Sync and let it start up again in standalone transport mode.
  GetClient(0)->StopSyncServiceWithoutClearingData();
  ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion(
      /*skip_passphrase_verification=*/false));
  ASSERT_EQ(syncer::SyncService::TransportState::ACTIVE,
            GetSyncService(0)->GetTransportState());
  ASSERT_FALSE(GetSyncService(0)->IsSyncFeatureActive());

  // Now start full Sync again.
  GetClient(0)->StartSyncService();
  ASSERT_TRUE(GetSyncService(0)->IsSyncFeatureActive());

  // The bookmark should still be there, *without* having been redownloaded.
  ASSERT_TRUE(bookmarks_helper::GetBookmarkModel(0)->IsBookmarked(
      GURL(kSyncedBookmarkURL)));
  EXPECT_EQ(0, GetNumUpdatesDownloadedInLastCycle());
}

}  // namespace
