// 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 "components/invalidation/impl/ticl_invalidation_service.h"

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/invalidation/impl/fake_invalidation_state_tracker.h"
#include "components/invalidation/impl/fake_invalidator.h"
#include "components/invalidation/impl/gcm_invalidation_bridge.h"
#include "components/invalidation/impl/invalidation_service_test_template.h"
#include "components/invalidation/impl/invalidation_state_tracker.h"
#include "components/invalidation/impl/invalidator.h"
#include "google_apis/gaia/fake_identity_provider.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace invalidation {

namespace {

class FakeTiclSettingsProvider : public TiclSettingsProvider {
 public:
  FakeTiclSettingsProvider();
  ~FakeTiclSettingsProvider() override;

  // TiclSettingsProvider:
  bool UseGCMChannel() const override;

 private:
  DISALLOW_COPY_AND_ASSIGN(FakeTiclSettingsProvider);
};

FakeTiclSettingsProvider::FakeTiclSettingsProvider() {
}

FakeTiclSettingsProvider::~FakeTiclSettingsProvider() {
}

bool FakeTiclSettingsProvider::UseGCMChannel() const {
  return false;
}

}  // namespace

class TiclInvalidationServiceTestDelegate {
 public:
  TiclInvalidationServiceTestDelegate() {}

  ~TiclInvalidationServiceTestDelegate() {
  }

  void CreateInvalidationService() {
    CreateUninitializedInvalidationService();
    InitializeInvalidationService();
  }

  void CreateUninitializedInvalidationService() {
    gcm_driver_.reset(new gcm::FakeGCMDriver());
    invalidation_service_.reset(new TiclInvalidationService(
        "TestUserAgent",
        scoped_ptr<IdentityProvider>(new FakeIdentityProvider(&token_service_)),
        scoped_ptr<TiclSettingsProvider>(new FakeTiclSettingsProvider),
        gcm_driver_.get(),
        NULL));
  }

  void InitializeInvalidationService() {
    fake_invalidator_ = new syncer::FakeInvalidator();
    invalidation_service_->InitForTest(
        scoped_ptr<syncer::InvalidationStateTracker>(
            new syncer::FakeInvalidationStateTracker),
        fake_invalidator_);
  }

  InvalidationService* GetInvalidationService() {
    return invalidation_service_.get();
  }

  void DestroyInvalidationService() {
    invalidation_service_.reset();
  }

  void TriggerOnInvalidatorStateChange(syncer::InvalidatorState state) {
    fake_invalidator_->EmitOnInvalidatorStateChange(state);
  }

  void TriggerOnIncomingInvalidation(
      const syncer::ObjectIdInvalidationMap& invalidation_map) {
    fake_invalidator_->EmitOnIncomingInvalidation(invalidation_map);
  }

  FakeOAuth2TokenService token_service_;
  scoped_ptr<gcm::GCMDriver> gcm_driver_;
  syncer::FakeInvalidator* fake_invalidator_;  // Owned by the service.

  scoped_ptr<TiclInvalidationService> invalidation_service_;
};

INSTANTIATE_TYPED_TEST_CASE_P(
    TiclInvalidationServiceTest, InvalidationServiceTest,
    TiclInvalidationServiceTestDelegate);

namespace internal {

class FakeCallbackContainer {
  public:
    FakeCallbackContainer() : called_(false),
                              weak_ptr_factory_(this) {}

    void FakeCallback(const base::DictionaryValue& value) {
      called_ = true;
    }

    bool called_;
    base::WeakPtrFactory<FakeCallbackContainer> weak_ptr_factory_;
};

}  // namespace internal

// Test that requesting for detailed status doesn't crash even if the
// underlying invalidator is not initialized.
TEST(TiclInvalidationServiceLoggingTest, DetailedStatusCallbacksWork) {
  scoped_ptr<TiclInvalidationServiceTestDelegate> delegate (
      new TiclInvalidationServiceTestDelegate());

  delegate->CreateUninitializedInvalidationService();
  invalidation::InvalidationService* const invalidator =
      delegate->GetInvalidationService();

  internal::FakeCallbackContainer fake_container;
  invalidator->RequestDetailedStatus(
      base::Bind(&internal::FakeCallbackContainer::FakeCallback,
                 fake_container.weak_ptr_factory_.GetWeakPtr()));
  EXPECT_FALSE(fake_container.called_);

  delegate->InitializeInvalidationService();

  invalidator->RequestDetailedStatus(
      base::Bind(&internal::FakeCallbackContainer::FakeCallback,
                 fake_container.weak_ptr_factory_.GetWeakPtr()));
  EXPECT_TRUE(fake_container.called_);
}

}  // namespace invalidation
