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

#include <stddef.h>

#include <algorithm>
#include <utility>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "remoting/test/fake_access_token_fetcher.h"
#include "remoting/test/fake_app_remoting_report_issue_request.h"
#include "remoting/test/fake_refresh_token_store.h"
#include "remoting/test/fake_remote_host_info_fetcher.h"
#include "remoting/test/mock_access_token_fetcher.h"
#include "remoting/test/refresh_token_store.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {
const char kAuthCodeValue[] = "4/892379827345jkefvkdfbv";
const char kUserNameValue[] = "remoting_user@gmail.com";
const char kTestApplicationId[] = "sadlkjlsjgadjfgoajdfgagb";
const char kAnotherTestApplicationId[] = "waklgoisdhfnvjkdsfbljn";
const char kTestHostId1[] = "awesome_test_host_id";
const char kTestHostId2[] = "super_awesome_test_host_id";
const char kTestHostId3[] = "uber_awesome_test_host_id";
}

namespace remoting {
namespace test {

using testing::_;

class AppRemotingTestDriverEnvironmentTest : public ::testing::Test {
 public:
  AppRemotingTestDriverEnvironmentTest();
  ~AppRemotingTestDriverEnvironmentTest() override;

  FakeAccessTokenFetcher* fake_access_token_fetcher() const {
    return fake_access_token_fetcher_;
  }

 protected:
  void Initialize();
  void Initialize(
      const AppRemotingTestDriverEnvironment::EnvironmentOptions& options);

  FakeAccessTokenFetcher* fake_access_token_fetcher_;
  FakeAppRemotingReportIssueRequest fake_report_issue_request_;
  FakeRefreshTokenStore fake_token_store_;
  FakeRemoteHostInfoFetcher fake_remote_host_info_fetcher_;
  MockAccessTokenFetcher mock_access_token_fetcher_;

  scoped_ptr<AppRemotingTestDriverEnvironment> environment_object_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AppRemotingTestDriverEnvironmentTest);
};

AppRemotingTestDriverEnvironmentTest::AppRemotingTestDriverEnvironmentTest()
    : fake_access_token_fetcher_(nullptr) {
}

AppRemotingTestDriverEnvironmentTest::~AppRemotingTestDriverEnvironmentTest() {
}

void AppRemotingTestDriverEnvironmentTest::Initialize() {
  AppRemotingTestDriverEnvironment::EnvironmentOptions options;
  options.user_name = kUserNameValue;
  options.service_environment = kDeveloperEnvironment;

  Initialize(options);
}

void AppRemotingTestDriverEnvironmentTest::Initialize(
    const AppRemotingTestDriverEnvironment::EnvironmentOptions& options) {
  environment_object_.reset(new AppRemotingTestDriverEnvironment(options));

  scoped_ptr<FakeAccessTokenFetcher> fake_access_token_fetcher(
      new FakeAccessTokenFetcher());
  fake_access_token_fetcher_ = fake_access_token_fetcher.get();
  mock_access_token_fetcher_.SetAccessTokenFetcher(
      std::move(fake_access_token_fetcher));

  environment_object_->SetAccessTokenFetcherForTest(
      &mock_access_token_fetcher_);
  environment_object_->SetAppRemotingReportIssueRequestForTest(
      &fake_report_issue_request_);
  environment_object_->SetRefreshTokenStoreForTest(&fake_token_store_);
  environment_object_->SetRemoteHostInfoFetcherForTest(
      &fake_remote_host_info_fetcher_);
}

TEST_F(AppRemotingTestDriverEnvironmentTest, InitializeObjectWithAuthCode) {
  Initialize();

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
      .Times(0);

  EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
  EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
  EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
            kFakeAccessTokenFetcherRefreshTokenValue);
  EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
  EXPECT_EQ(environment_object_->access_token(),
            kFakeAccessTokenFetcherAccessTokenValue);

  // Attempt to init again, we should not see any additional calls or errors.
  EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       InitializeObjectWithAuthCodeFailed) {
  Initialize();

  fake_access_token_fetcher()->set_fail_access_token_from_auth_code(true);

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
      .Times(0);

  EXPECT_FALSE(environment_object_->Initialize(kAuthCodeValue));
  EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}

TEST_F(AppRemotingTestDriverEnvironmentTest, InitializeObjectWithRefreshToken) {
  Initialize();

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
      .Times(0);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  // We should not write the refresh token a second time if we read from the
  // disk originally.
  EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());

  // Verify the object was initialized correctly.
  EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
  EXPECT_EQ(environment_object_->access_token(),
            kFakeAccessTokenFetcherAccessTokenValue);

  // Attempt to init again, we should not see any additional calls or errors.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));
}

TEST_F(AppRemotingTestDriverEnvironmentTest, TearDownAfterInitializeSucceeds) {
  Initialize();

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
      .Times(0);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  // Note: We are using a static cast here because the TearDown() method is
  //       private as it is an interface method that we only want to call
  //       directly in tests or by the GTEST framework.
  static_cast<testing::Environment*>(environment_object_.get())->TearDown();
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       InitializeObjectWithRefreshTokenFailed) {
  Initialize();

  fake_access_token_fetcher()->set_fail_access_token_from_refresh_token(true);

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
      .Times(0);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_FALSE(environment_object_->Initialize(std::string()));
  EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       InitializeObjectNoAuthCodeOrRefreshToken) {
  Initialize();

  // Neither method should be called in this scenario.
  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _))
      .Times(0);

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
      .Times(0);

  // Clear out the 'stored' refresh token value.
  fake_token_store_.set_refresh_token_value(std::string());

  // With no auth code or refresh token, then the initialization should fail.
  EXPECT_FALSE(environment_object_->Initialize(std::string()));
  EXPECT_FALSE(fake_token_store_.refresh_token_write_attempted());
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       InitializeObjectWithAuthCodeWriteFailed) {
  Initialize();

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));

  EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromRefreshToken(_, _))
      .Times(0);

  // Simulate a failure writing the token to the disk.
  fake_token_store_.set_refresh_token_write_succeeded(false);

  EXPECT_FALSE(environment_object_->Initialize(kAuthCodeValue));
  EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       RefreshAccessTokenAfterUsingAuthCode) {
  Initialize();

  {
    testing::InSequence call_sequence;

    EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));

    EXPECT_CALL(mock_access_token_fetcher_,
                GetAccessTokenFromRefreshToken(_, _));
  }

  EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
  EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
  EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
            kFakeAccessTokenFetcherRefreshTokenValue);
  EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
  EXPECT_EQ(environment_object_->access_token(),
            kFakeAccessTokenFetcherAccessTokenValue);

  // Attempt to init again, we should not see any additional calls or errors.
  EXPECT_TRUE(environment_object_->RefreshAccessToken());
}

TEST_F(AppRemotingTestDriverEnvironmentTest, RefreshAccessTokenFailure) {
  Initialize();

  {
    testing::InSequence call_sequence;

    // Mock is set up for this call to succeed.
    EXPECT_CALL(mock_access_token_fetcher_, GetAccessTokenFromAuthCode(_, _));

    // Mock is set up for this call to fail.
    EXPECT_CALL(mock_access_token_fetcher_,
                GetAccessTokenFromRefreshToken(_, _));
  }

  EXPECT_TRUE(environment_object_->Initialize(kAuthCodeValue));
  EXPECT_TRUE(fake_token_store_.refresh_token_write_attempted());
  EXPECT_EQ(fake_token_store_.stored_refresh_token_value(),
            kFakeAccessTokenFetcherRefreshTokenValue);
  EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
  EXPECT_EQ(environment_object_->access_token(),
            kFakeAccessTokenFetcherAccessTokenValue);

  fake_access_token_fetcher()->set_fail_access_token_from_refresh_token(true);

  // We expect the refresh to have failed, the user name to remain valid,
  // and the access token to have been cleared.
  EXPECT_FALSE(environment_object_->RefreshAccessToken());
  EXPECT_TRUE(environment_object_->access_token().empty());
  EXPECT_EQ(environment_object_->user_name(), kUserNameValue);
}

TEST_F(AppRemotingTestDriverEnvironmentTest, GetRemoteHostInfoSuccess) {
  Initialize();

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  RemoteHostInfo remote_host_info;
  EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
  EXPECT_TRUE(remote_host_info.IsReadyForConnection());
}

TEST_F(AppRemotingTestDriverEnvironmentTest, GetRemoteHostInfoFailure) {
  Initialize();

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  fake_remote_host_info_fetcher_.set_fail_retrieve_remote_host_info(true);

  RemoteHostInfo remote_host_info;
  EXPECT_FALSE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
}

TEST_F(AppRemotingTestDriverEnvironmentTest,
       GetRemoteHostInfoWithoutInitializing) {
  Initialize();

  RemoteHostInfo remote_host_info;
  EXPECT_FALSE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
}

TEST_F(AppRemotingTestDriverEnvironmentTest, NoRemoteHostsReleasedOnTearDown) {
  // Use the default options as the flag to release the remote hosts is not
  // enabled by default.
  Initialize();

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  RemoteHostInfo remote_host_info;
  EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
  EXPECT_TRUE(remote_host_info.IsReadyForConnection());

  EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);

  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);

  // Note: We are using a static cast here because the TearDown() method is
  //       private as it is an interface method that we only want to call
  //       directly in tests or by the GTEST framework.
  static_cast<testing::Environment*>(environment_object_.get())->TearDown();

  // Verify no hosts were released via a report issue request.
  EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);
}

TEST_F(AppRemotingTestDriverEnvironmentTest, OneRemoteHostReleasedOnTearDown) {
  AppRemotingTestDriverEnvironment::EnvironmentOptions options;
  options.user_name = kUserNameValue;
  options.release_hosts_when_done = true;
  options.service_environment = kDeveloperEnvironment;
  Initialize(options);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  RemoteHostInfo remote_host_info;
  EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
  EXPECT_TRUE(remote_host_info.IsReadyForConnection());

  EXPECT_EQ(fake_report_issue_request_.get_host_ids_released().size(), 0UL);

  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);

  // Note: We are using a static cast here because the TearDown() method is
  //       private as it is an interface method that we only want to call
  //       directly in tests or by the GTEST framework.
  static_cast<testing::Environment*>(environment_object_.get())->TearDown();

  std::string expected_host(
      MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));
  std::vector<std::string> actual_host_list =
      fake_report_issue_request_.get_host_ids_released();

  EXPECT_EQ(actual_host_list.size(), 1UL);
  EXPECT_EQ(actual_host_list[0], expected_host);
}

TEST_F(AppRemotingTestDriverEnvironmentTest, RemoteHostsReleasedOnTearDown) {
  AppRemotingTestDriverEnvironment::EnvironmentOptions options;
  options.user_name = kUserNameValue;
  options.release_hosts_when_done = true;
  options.service_environment = kDeveloperEnvironment;
  Initialize(options);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  RemoteHostInfo remote_host_info;
  EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
  EXPECT_TRUE(remote_host_info.IsReadyForConnection());

  std::vector<std::string> expected_host_list;
  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
  expected_host_list.push_back(
      MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));

  environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
                                            kTestHostId2);
  expected_host_list.push_back(MakeFormattedStringForReleasedHost(
      kAnotherTestApplicationId, kTestHostId2));

  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);
  expected_host_list.push_back(
      MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId3));

  // Note: We are using a static cast here because the TearDown() method is
  //       private as it is an interface method that we only want to call
  //       directly in tests or by the GTEST framework.
  static_cast<testing::Environment*>(environment_object_.get())->TearDown();

  std::vector<std::string> actual_host_list =
      fake_report_issue_request_.get_host_ids_released();

  std::sort(actual_host_list.begin(), actual_host_list.end());
  std::sort(expected_host_list.begin(), expected_host_list.end());

  EXPECT_EQ(actual_host_list.size(), expected_host_list.size());
  for (size_t i = 0; i < actual_host_list.size(); ++i) {
    EXPECT_EQ(actual_host_list[i], expected_host_list[i]);
  }
}

TEST_F(AppRemotingTestDriverEnvironmentTest, RemoteHostsReleasedOnce) {
  AppRemotingTestDriverEnvironment::EnvironmentOptions options;
  options.user_name = kUserNameValue;
  options.release_hosts_when_done = true;
  options.service_environment = kDeveloperEnvironment;
  Initialize(options);

  // Pass in an empty auth code since we are using a refresh token.
  EXPECT_TRUE(environment_object_->Initialize(std::string()));

  RemoteHostInfo remote_host_info;
  EXPECT_TRUE(environment_object_->GetRemoteHostInfoForApplicationId(
      kTestApplicationId, &remote_host_info));
  EXPECT_TRUE(remote_host_info.IsReadyForConnection());

  std::vector<std::string> expected_host_list;
  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
  expected_host_list.push_back(
      MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId1));

  environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
                                            kTestHostId2);
  expected_host_list.push_back(MakeFormattedStringForReleasedHost(
      kAnotherTestApplicationId, kTestHostId2));

  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);
  expected_host_list.push_back(
      MakeFormattedStringForReleasedHost(kTestApplicationId, kTestHostId3));

  // Attempt to add the previous hosts again, they should not be added since
  // they will already exist in the list of hosts to release.
  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId1);
  environment_object_->AddHostToReleaseList(kAnotherTestApplicationId,
                                            kTestHostId2);
  environment_object_->AddHostToReleaseList(kTestApplicationId, kTestHostId3);

  // Note: We are using a static cast here because the TearDown() method is
  //       private as it is an interface method that we only want to call
  //       directly in tests or by the GTEST framework.
  static_cast<testing::Environment*>(environment_object_.get())->TearDown();

  std::vector<std::string> actual_host_list =
      fake_report_issue_request_.get_host_ids_released();

  std::sort(actual_host_list.begin(), actual_host_list.end());
  std::sort(expected_host_list.begin(), expected_host_list.end());

  EXPECT_EQ(actual_host_list.size(), expected_host_list.size());
  for (size_t i = 0; i < actual_host_list.size(); ++i) {
    EXPECT_EQ(actual_host_list[i], expected_host_list[i]);
  }
}

}  // namespace test
}  // namespace remoting
