// 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/gcm_invalidation_bridge.h"

#include <memory>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "components/gcm_driver/gcm_driver.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "google_apis/gaia/fake_identity_provider.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/base/ip_endpoint.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace invalidation {
namespace {

// Implementation of GCMDriver::Register that always succeeds with the same
// registrationId.
class CustomFakeGCMDriver : public gcm::FakeGCMDriver {
 public:
  CustomFakeGCMDriver() {}
  ~CustomFakeGCMDriver() override {}

 protected:
  // FakeGCMDriver override:
  void RegisterImpl(const std::string& app_id,
                    const std::vector<std::string>& sender_ids) override {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&CustomFakeGCMDriver::RegisterFinished,
                   base::Unretained(this), app_id,
                   std::string("registration.id"), gcm::GCMClient::SUCCESS));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver);
};

class GCMInvalidationBridgeTest : public ::testing::Test {
 protected:
  GCMInvalidationBridgeTest()
      : connection_online_(false) {}

  ~GCMInvalidationBridgeTest() override {}

  void SetUp() override {
    token_service_.reset(new FakeProfileOAuth2TokenService());
    token_service_->set_auto_post_fetch_response_on_message_loop(true);
    token_service_->UpdateCredentials("", "fake_refresh_token");
    gcm_driver_.reset(new CustomFakeGCMDriver());

    identity_provider_.reset(new FakeIdentityProvider(token_service_.get()));
    bridge_.reset(new GCMInvalidationBridge(gcm_driver_.get(),
                                            identity_provider_.get()));

    delegate_ = bridge_->CreateDelegate();
    delegate_->Initialize(
        base::Bind(&GCMInvalidationBridgeTest::ConnectionStateChanged,
                   base::Unretained(this)),
        base::Bind(&base::DoNothing) /* store_reset_callback */);
    RunLoop();
  }

  void RunLoop() {
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }

 public:
  void RegisterFinished(const std::string& registration_id,
                        gcm::GCMClient::Result result) {
    registration_id_ = registration_id;
  }

  void RequestTokenFinished(const GoogleServiceAuthError& error,
                            const std::string& token) {
    issued_tokens_.push_back(token);
    request_token_errors_.push_back(error);
  }

  void ConnectionStateChanged(bool online) {
    connection_online_ = online;
  }

  base::MessageLoop message_loop_;
  std::unique_ptr<FakeProfileOAuth2TokenService> token_service_;
  std::unique_ptr<gcm::GCMDriver> gcm_driver_;
  std::unique_ptr<FakeIdentityProvider> identity_provider_;

  std::vector<std::string> issued_tokens_;
  std::vector<GoogleServiceAuthError> request_token_errors_;
  std::string registration_id_;
  bool connection_online_;

  std::unique_ptr<GCMInvalidationBridge> bridge_;
  std::unique_ptr<syncer::GCMNetworkChannelDelegate> delegate_;
};

TEST_F(GCMInvalidationBridgeTest, RequestToken) {
  // Make sure that call to RequestToken reaches OAuth2TokenService and gets
  // back to callback.
  delegate_->RequestToken(
      base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
                 base::Unretained(this)));
  RunLoop();
  EXPECT_EQ(1U, issued_tokens_.size());
  EXPECT_NE("", issued_tokens_[0]);
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), request_token_errors_[0]);
}

TEST_F(GCMInvalidationBridgeTest, RequestTokenTwoConcurrentRequests) {
  // First call should finish with REQUEST_CANCELLED error.
  delegate_->RequestToken(
      base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
                 base::Unretained(this)));
  // Second request should succeed.
  delegate_->RequestToken(
      base::Bind(&GCMInvalidationBridgeTest::RequestTokenFinished,
                 base::Unretained(this)));
  RunLoop();

  EXPECT_EQ(2U, issued_tokens_.size());

  EXPECT_EQ("", issued_tokens_[0]);
  EXPECT_EQ(GoogleServiceAuthError::REQUEST_CANCELED,
            request_token_errors_[0].state());

  EXPECT_NE("", issued_tokens_[1]);
  EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), request_token_errors_[1]);
}

TEST_F(GCMInvalidationBridgeTest, Register) {
  EXPECT_TRUE(registration_id_.empty());
  delegate_->Register(base::Bind(&GCMInvalidationBridgeTest::RegisterFinished,
                                 base::Unretained(this)));
  RunLoop();

  EXPECT_FALSE(registration_id_.empty());
}

TEST_F(GCMInvalidationBridgeTest, ConnectionState) {
  EXPECT_FALSE(connection_online_);
  bridge_->OnConnected(net::IPEndPoint());
  RunLoop();
  EXPECT_TRUE(connection_online_);
  bridge_->OnDisconnected();
  RunLoop();
  EXPECT_FALSE(connection_online_);
}

}  // namespace
}  // namespace invalidation
