// Copyright 2015 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 "remoting/host/gcd_state_updater.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringize_macros.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "remoting/base/constants.h"
#include "remoting/base/fake_oauth_token_getter.h"
#include "remoting/host/gcd_rest_client.h"
#include "remoting/signaling/fake_signal_strategy.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Return;

namespace remoting {

class GcdStateUpdaterTest : public testing::Test {
 public:
  GcdStateUpdaterTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
            base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED),
        test_shared_url_loader_factory_(
            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
                &test_url_loader_factory_)),
        token_getter_(OAuthTokenGetter::SUCCESS,
                      "<fake_user_email>",
                      "<fake_access_token>"),
        rest_client_(new GcdRestClient("http://gcd_base_url",
                                       "<gcd_device_id>",
                                       test_shared_url_loader_factory_,
                                       &token_getter_)),
        signal_strategy_(SignalingAddress("local_jid")) {
    rest_client_->SetClockForTest(&test_clock_);
  }

  void OnSuccess() { on_success_count_++; }

  void OnHostIdError() { on_host_id_error_count_++; }

  network::TestURLLoaderFactory::PendingRequest* GetPendingRequest(
      size_t index = 0) {
    if (index >= test_url_loader_factory_.pending_requests()->size())
      return nullptr;
    auto* request = &(*test_url_loader_factory_.pending_requests())[index];
    DCHECK(request);
    return request;
  }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  base::SimpleTestClock test_clock_;
  net::TestURLFetcherFactory url_fetcher_factory_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory>
      test_shared_url_loader_factory_;
  FakeOAuthTokenGetter token_getter_;
  std::unique_ptr<GcdRestClient> rest_client_;
  FakeSignalStrategy signal_strategy_;
  int on_success_count_ = 0;
  int on_host_id_error_count_ = 0;
};

TEST_F(GcdStateUpdaterTest, Success) {
  std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater(
      base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)),
      base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)),
      &signal_strategy_, std::move(rest_client_)));

  test_url_loader_factory_.SetInterceptor(
      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
        EXPECT_EQ("{\"patches\":[{\"patch\":{"
            "\"base\":{\"_hostVersion\":\"" STRINGIZE(VERSION) "\","
            "\"_jabberId\":\"local_jid\"}},"
            "\"timeMs\":0.0}],\"requestTimeMs\":0.0}",
            network::GetUploadData(request));

        test_url_loader_factory_.AddResponse(request.url.spec(), std::string(),
                                             net::HTTP_OK);
      }));

  signal_strategy_.Connect();
  scoped_task_environment_.RunUntilIdle();

  EXPECT_EQ(1, on_success_count_);

  updater.reset();

  EXPECT_EQ(0, on_host_id_error_count_);
}

TEST_F(GcdStateUpdaterTest, QueuedRequests) {
  std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater(
      base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)),
      base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)),
      &signal_strategy_, std::move(rest_client_)));

  // Connect, then re-connect with a different JID while the status
  // update for the first connection is pending.
  signal_strategy_.Connect();
  scoped_task_environment_.RunUntilIdle();
  signal_strategy_.Disconnect();
  scoped_task_environment_.RunUntilIdle();
  signal_strategy_.SetLocalAddress(SignalingAddress("local_jid2"));
  signal_strategy_.Connect();
  scoped_task_environment_.RunUntilIdle();

  // Let the first status update finish.  This should be a no-op in
  // the updater because the local JID has changed since this request
  // was issued.
  auto* request = GetPendingRequest(0);
  test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
      request, std::string());

  EXPECT_EQ(0, on_success_count_);

  test_url_loader_factory_.SetInterceptor(
      base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
        EXPECT_EQ("{\"patches\":[{\"patch\":{"
            "\"base\":{\"_hostVersion\":\"" STRINGIZE(VERSION) "\","
            "\"_jabberId\":\"local_jid2\"}},"
            "\"timeMs\":0.0}],\"requestTimeMs\":0.0}",
            network::GetUploadData(request));
        test_url_loader_factory_.AddResponse(request.url.spec(), std::string(),
                                             net::HTTP_OK);
        scoped_task_environment_.RunUntilIdle();
      }));

  // Wait for the next retry.
  scoped_task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));

  // There should be a new pending request now with the new local JID.
  // It will be caught and handled by the interceptor installed above.
  EXPECT_EQ(1, on_success_count_);

  updater.reset();

  EXPECT_EQ(0, on_host_id_error_count_);
}

TEST_F(GcdStateUpdaterTest, Retry) {
  std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater(
      base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)),
      base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)),
      &signal_strategy_, std::move(rest_client_)));

  signal_strategy_.Connect();
  scoped_task_environment_.RunUntilIdle();

  auto* request = GetPendingRequest(0);
  test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
      request, network::ResourceResponseHead(), std::string(),
      network::URLLoaderCompletionStatus(net::ERR_FAILED));

  scoped_task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(1));

  request = GetPendingRequest(1);
  test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
      request, network::CreateResourceResponseHead(net::HTTP_OK), std::string(),
      network::URLLoaderCompletionStatus());
  EXPECT_EQ(1, on_success_count_);

  updater.reset();

  EXPECT_EQ(0, on_host_id_error_count_);
}

TEST_F(GcdStateUpdaterTest, UnknownHost) {
  std::unique_ptr<GcdStateUpdater> updater(new GcdStateUpdater(
      base::Bind(&GcdStateUpdaterTest::OnSuccess, base::Unretained(this)),
      base::Bind(&GcdStateUpdaterTest::OnHostIdError, base::Unretained(this)),
      &signal_strategy_, std::move(rest_client_)));

  signal_strategy_.Connect();
  scoped_task_environment_.RunUntilIdle();

  auto* request = GetPendingRequest(0);
  test_url_loader_factory_.SimulateResponseWithoutRemovingFromPendingList(
      request, network::CreateResourceResponseHead(net::HTTP_NOT_FOUND),
      std::string(), network::URLLoaderCompletionStatus(net::OK));
  EXPECT_EQ(0, on_success_count_);
  EXPECT_EQ(1, on_host_id_error_count_);
}

}  // namespace remoting
