// 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_;

  std::unique_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));

  std::unique_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
