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

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "remoting/test/access_token_fetcher.h"
#include "remoting/test/host_list_fetcher.h"
#include "remoting/test/refresh_token_store.h"

namespace remoting {
namespace test {

ChromotingTestDriverEnvironment* g_chromoting_shared_data = nullptr;

ChromotingTestDriverEnvironment::EnvironmentOptions::EnvironmentOptions() =
    default;

ChromotingTestDriverEnvironment::EnvironmentOptions::~EnvironmentOptions() =
    default;

ChromotingTestDriverEnvironment::ChromotingTestDriverEnvironment(
    const EnvironmentOptions& options)
    : host_name_(options.host_name),
      host_jid_(options.host_jid),
      user_name_(options.user_name),
      pin_(options.pin),
      refresh_token_file_path_(options.refresh_token_file_path),
      use_test_environment_(options.use_test_environment) {
  DCHECK(!user_name_.empty());
  DCHECK(!host_name_.empty());
}

ChromotingTestDriverEnvironment::~ChromotingTestDriverEnvironment() = default;

bool ChromotingTestDriverEnvironment::Initialize(
    const std::string& auth_code) {
  if (!access_token_.empty()) {
    return true;
  }

  if (!base::MessageLoop::current()) {
    message_loop_.reset(new base::MessageLoopForIO);
  }

  // If a unit test has set |test_refresh_token_store_| then we should use it
  // below.  Note that we do not want to destroy the test object.
  std::unique_ptr<RefreshTokenStore> temporary_refresh_token_store;
  RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
  if (!refresh_token_store) {
    temporary_refresh_token_store =
        RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
    refresh_token_store = temporary_refresh_token_store.get();
  }

  // Check to see if we have a refresh token stored for this user.
  refresh_token_ = refresh_token_store->FetchRefreshToken();
  if (refresh_token_.empty()) {
    // This isn't necessarily an error as this might be a first run scenario.
    VLOG(2) << "No refresh token stored for " << user_name_;

    if (auth_code.empty()) {
      // No token and no Auth code means no service connectivity, bail!
      LOG(ERROR) << "Cannot retrieve an access token without a stored refresh"
                 << " token on disk or an auth_code passed into the tool";
      return false;
    }
  }

  if (!RetrieveAccessToken(auth_code)) {
    // If we cannot retrieve an access token, then nothing is going to work.
    // Let the caller know that our object is not ready to be used.
    return false;
  }

  return true;
}

void ChromotingTestDriverEnvironment::DisplayHostList() {
  const char kHostAvailabilityFormatString[] = "%-25s%-15s%-35s\n";

  printf(kHostAvailabilityFormatString, "Host Name", "Host Status", "Host JID");
  printf(kHostAvailabilityFormatString, "---------", "-----------", "--------");

  std::string status;
  for (const HostInfo& host_info : host_list_) {
    HostStatus host_status = host_info.status;
    if (host_status == kHostStatusOnline) {
      status = "ONLINE";
    } else if (host_status == kHostStatusOffline) {
      status = "OFFLINE";
    } else {
      status = "UNKNOWN";
    }

    printf(kHostAvailabilityFormatString, host_info.host_name.c_str(),
           status.c_str(), host_info.host_jid.c_str());
  }
}

bool ChromotingTestDriverEnvironment::WaitForHostOnline() {
  if (host_list_.empty()) {
    RetrieveHostList();
  }

  DisplayHostList();

  // Refresh the |host_list_| periodically to check if expected JID is online.
  const base::TimeDelta kTotalTimeInSeconds = base::TimeDelta::FromSeconds(60);
  const base::TimeDelta kSleepTimeInSeconds = base::TimeDelta::FromSeconds(5);
  const int kMaxIterations = kTotalTimeInSeconds / kSleepTimeInSeconds;

  for (int iterations = 0; iterations < kMaxIterations; iterations++) {
    if (!FindHostInHostList()) {
      LOG(WARNING) << "Host '" << host_name_ << "' with JID '" << host_jid_
                   << "' not found in host list.";
      return false;
    }

    if (host_info_.IsReadyForConnection()) {
      if (iterations > 0) {
        VLOG(0) << "Host online after: "
                << iterations * kSleepTimeInSeconds.InSeconds() << " seconds.";
      }
      return true;
    }

    // Wait a while before refreshing host list.
    base::PlatformThread::Sleep(kSleepTimeInSeconds);
    RefreshHostList();
  }

  LOG(ERROR) << "Host '" << host_name_ << "' with JID '" << host_jid_
             << "' still not online after "
             << kMaxIterations * kSleepTimeInSeconds.InSeconds() << " seconds.";
  return false;
}

bool ChromotingTestDriverEnvironment::FindHostInHostList() {
  bool host_found = false;
  for (HostInfo& host_info : host_list_) {
    // The JID is optional so we consider an empty string to be a '*' match.
    bool host_jid_match =
        host_jid_.empty() || (host_jid_ == host_info.host_jid);
    bool host_name_match = host_name_ == host_info.host_name;

    if (host_name_match && host_jid_match) {
      host_info_ = host_info;
      host_found = true;
      break;
    }
  }
  return host_found;
}

void ChromotingTestDriverEnvironment::SetAccessTokenFetcherForTest(
    AccessTokenFetcher* access_token_fetcher) {
  DCHECK(access_token_fetcher);

  test_access_token_fetcher_ = access_token_fetcher;
}

void ChromotingTestDriverEnvironment::SetRefreshTokenStoreForTest(
    RefreshTokenStore* refresh_token_store) {
  DCHECK(refresh_token_store);

  test_refresh_token_store_ = refresh_token_store;
}

void ChromotingTestDriverEnvironment::SetHostListFetcherForTest(
    HostListFetcher* host_list_fetcher) {
  DCHECK(host_list_fetcher);

  test_host_list_fetcher_ = host_list_fetcher;
}

void ChromotingTestDriverEnvironment::SetHostNameForTest(
    const std::string& host_name) {
  host_name_ = host_name;
}

void ChromotingTestDriverEnvironment::SetHostJidForTest(
    const std::string& host_jid) {
  host_jid_ = host_jid;
}

void ChromotingTestDriverEnvironment::TearDown() {
  // Letting the MessageLoop tear down during the test destructor results in
  // errors after test completion, when the MessageLoop dtor touches the
  // registered AtExitManager. The AtExitManager is torn down before the test
  // destructor is executed, so we tear down the MessageLoop here, while it is
  // still valid.
  message_loop_.reset();
}

bool ChromotingTestDriverEnvironment::RetrieveAccessToken(
    const std::string& auth_code) {
  base::RunLoop run_loop;

  access_token_.clear();

  AccessTokenCallback access_token_callback =
      base::Bind(&ChromotingTestDriverEnvironment::OnAccessTokenRetrieved,
                 base::Unretained(this), run_loop.QuitClosure());

  // If a unit test has set |test_access_token_fetcher_| then we should use it
  // below.  Note that we do not want to destroy the test object at the end of
  // the function which is why we have the dance below.
  std::unique_ptr<AccessTokenFetcher> temporary_access_token_fetcher;
  AccessTokenFetcher* access_token_fetcher = test_access_token_fetcher_;
  if (!access_token_fetcher) {
    temporary_access_token_fetcher.reset(new AccessTokenFetcher());
    access_token_fetcher = temporary_access_token_fetcher.get();
  }

  if (!auth_code.empty()) {
    // If the user passed in an authcode, then use it to retrieve an
    // updated access/refresh token.
    access_token_fetcher->GetAccessTokenFromAuthCode(auth_code,
                                                     access_token_callback);
  } else {
    DCHECK(!refresh_token_.empty());

    access_token_fetcher->GetAccessTokenFromRefreshToken(refresh_token_,
                                                         access_token_callback);
  }

  run_loop.Run();

  // If we were using an auth_code and received a valid refresh token,
  // then we want to store it locally.  If we had an auth code and did not
  // receive a refresh token, then we should let the user know and exit.
  if (!auth_code.empty()) {
    if (!refresh_token_.empty()) {
      // If a unit test has set |test_refresh_token_store_| then we should use
      // it below.  Note that we do not want to destroy the test object.
      std::unique_ptr<RefreshTokenStore> temporary_refresh_token_store;
      RefreshTokenStore* refresh_token_store = test_refresh_token_store_;
      if (!refresh_token_store) {
        temporary_refresh_token_store =
            RefreshTokenStore::OnDisk(user_name_, refresh_token_file_path_);
        refresh_token_store = temporary_refresh_token_store.get();
      }

      if (!refresh_token_store->StoreRefreshToken(refresh_token_)) {
        // If we failed to persist the refresh token, then we should let the
        // user sort out the issue before continuing.
        return false;
      }
    } else {
      LOG(ERROR) << "Failed to use AUTH CODE to retrieve a refresh token.\n"
                 << "Was the one-time use AUTH CODE used more than once?";
      return false;
    }
  }

  if (access_token_.empty()) {
    LOG(ERROR) << "Failed to retrieve access token.";
    return false;
  }

  return true;
}

void ChromotingTestDriverEnvironment::OnAccessTokenRetrieved(
    base::Closure done_closure,
    const std::string& retrieved_access_token,
    const std::string& retrieved_refresh_token) {
  VLOG(1) << "OnAccessTokenRetrieved() Called";
  VLOG(1) << "Access Token: " << retrieved_access_token;

  access_token_ = retrieved_access_token;
  refresh_token_ = retrieved_refresh_token;

  done_closure.Run();
}

bool ChromotingTestDriverEnvironment::RefreshHostList() {
  host_list_.clear();

  return RetrieveHostList();
}

bool ChromotingTestDriverEnvironment::RetrieveHostList() {
  base::RunLoop run_loop;

  // Clear the previous host info.
  host_info_ = HostInfo();

  // If a unit test has set |test_host_list_fetcher_| then we should use it
  // below.  Note that we do not want to destroy the test object at the end of
  // the function which is why we have the dance below.
  std::unique_ptr<HostListFetcher> temporary_host_list_fetcher;
  HostListFetcher* host_list_fetcher = test_host_list_fetcher_;
  if (!host_list_fetcher) {
    temporary_host_list_fetcher.reset(new HostListFetcher());
    host_list_fetcher = temporary_host_list_fetcher.get();
  }

  remoting::test::HostListFetcher::HostlistCallback host_list_callback =
      base::Bind(&ChromotingTestDriverEnvironment::OnHostListRetrieved,
                 base::Unretained(this), run_loop.QuitClosure());

  host_list_fetcher->RetrieveHostlist(
      access_token_,
      use_test_environment_ ? kHostListTestRequestUrl : kHostListProdRequestUrl,
      host_list_callback);

  run_loop.Run();

  if (host_list_.empty()) {
    // Note: Access token may have expired, but it is unlikely.
    LOG(ERROR) << "Retrieved host list is empty.\n"
               << "Does the account have hosts set up?";
    return false;
  }

  return true;
}

void ChromotingTestDriverEnvironment::OnHostListRetrieved(
    base::Closure done_closure,
    const std::vector<HostInfo>& retrieved_host_list) {
  VLOG(1) << "OnHostListRetrieved() Called";

  host_list_ = retrieved_host_list;

  done_closure.Run();
}

}  // namespace test
}  // namespace remoting
