// Copyright 2018 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 "chromeos/services/multidevice_setup/host_backend_delegate_impl.h"

#include <algorithm>
#include <sstream>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/stl_util.h"
#include "chromeos/components/multidevice/logging/logging.h"
#include "chromeos/components/multidevice/software_feature.h"
#include "chromeos/components/multidevice/software_feature_state.h"
#include "chromeos/services/multidevice_setup/eligible_host_devices_provider.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"

namespace chromeos {

namespace multidevice_setup {

namespace {

// Name of the pref which stores the device ID of the host which is pending
// being set on the back-end.
const char kPendingRequestHostIdPrefName[] =
    "multidevice_setup.pending_request_host_id";

// String to use for the pending host ID preference entry when the pending
// request is to remove the current host.
const char kPendingRemovalOfCurrentHost[] = "pendingRemovalOfCurrentHost";

// String to use for the pending host ID when there is no pending request.
const char kNoPendingRequest[] = "";

// The number of minutes to wait before retrying a failed attempt.
const int kNumMinutesBetweenRetries = 5;

const char kNoHostForLogging[] = "[no host]";

}  // namespace

// static
HostBackendDelegateImpl::Factory*
    HostBackendDelegateImpl::Factory::test_factory_ = nullptr;

// static
HostBackendDelegateImpl::Factory* HostBackendDelegateImpl::Factory::Get() {
  if (test_factory_)
    return test_factory_;

  static base::NoDestructor<Factory> factory;
  return factory.get();
}

// static
void HostBackendDelegateImpl::Factory::SetFactoryForTesting(
    Factory* test_factory) {
  test_factory_ = test_factory;
}

HostBackendDelegateImpl::Factory::~Factory() = default;

std::unique_ptr<HostBackendDelegate>
HostBackendDelegateImpl::Factory::BuildInstance(
    EligibleHostDevicesProvider* eligible_host_devices_provider,
    PrefService* pref_service,
    device_sync::DeviceSyncClient* device_sync_client,
    std::unique_ptr<base::OneShotTimer> timer) {
  return base::WrapUnique(
      new HostBackendDelegateImpl(eligible_host_devices_provider, pref_service,
                                  device_sync_client, std::move(timer)));
}

// static
void HostBackendDelegateImpl::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterStringPref(kPendingRequestHostIdPrefName,
                               kNoPendingRequest);
}

HostBackendDelegateImpl::HostBackendDelegateImpl(
    EligibleHostDevicesProvider* eligible_host_devices_provider,
    PrefService* pref_service,
    device_sync::DeviceSyncClient* device_sync_client,
    std::unique_ptr<base::OneShotTimer> timer)
    : HostBackendDelegate(),
      eligible_host_devices_provider_(eligible_host_devices_provider),
      pref_service_(pref_service),
      device_sync_client_(device_sync_client),
      timer_(std::move(timer)),
      weak_ptr_factory_(this) {
  device_sync_client_->AddObserver(this);

  host_from_last_sync_ = GetHostFromDeviceSync();

  if (HasPendingHostRequest())
    AttemptNetworkRequest(false /* is_retry */);
}

HostBackendDelegateImpl::~HostBackendDelegateImpl() {
  device_sync_client_->RemoveObserver(this);
}

void HostBackendDelegateImpl::AttemptToSetMultiDeviceHostOnBackend(
    const base::Optional<multidevice::RemoteDeviceRef>& host_device) {
  if (host_device && !IsHostEligible(*host_device)) {
    PA_LOG(WARNING) << "HostBackendDelegateImpl::"
                    << "AttemptToSetMultiDeviceHostOnBackend(): Tried to set a "
                    << "device as host, but that device is not an eligible "
                    << "host. Device ID: "
                    << host_device->GetTruncatedDeviceIdForLogs();
    return;
  }

  // If the device on the back-end is already |host_device|, there no longer
  // needs to be a pending request.
  if (host_from_last_sync_ == host_device) {
    SetPendingHostRequest(kNoPendingRequest);
    return;
  }

  // Stop the timer, since a new attempt is being started.
  timer_->Stop();

  if (host_device)
    SetPendingHostRequest(host_device->GetDeviceId());
  else
    SetPendingHostRequest(kPendingRemovalOfCurrentHost);

  AttemptNetworkRequest(false /* is_retry */);
}

bool HostBackendDelegateImpl::HasPendingHostRequest() {
  const std::string pending_host_id_from_prefs =
      pref_service_->GetString(kPendingRequestHostIdPrefName);

  if (pending_host_id_from_prefs == kNoPendingRequest)
    return false;

  if (pending_host_id_from_prefs == kPendingRemovalOfCurrentHost) {
    // If the pending request is to remove the current host but there is no
    // current host, the host was removed by another device while this device
    // was offline.
    if (!host_from_last_sync_) {
      SetPendingHostRequest(kNoPendingRequest);
      return false;
    }

    // Otherwise, there still is a pending request to remove the current host.
    return true;
  }

  // By this point, |pending_host_id_from_prefs| refers to a real device ID and
  // not one of the two sentinel values.
  for (const auto& remote_device : device_sync_client_->GetSyncedDevices()) {
    if (pending_host_id_from_prefs == remote_device.GetDeviceId())
      return true;
  }

  // If a request was pending for a specific host device, but that device is no
  // longer present on the user's account, there is no longer a pending request.
  SetPendingHostRequest(kNoPendingRequest);
  return false;
}

base::Optional<multidevice::RemoteDeviceRef>
HostBackendDelegateImpl::GetPendingHostRequest() const {
  const std::string pending_host_id_from_prefs =
      pref_service_->GetString(kPendingRequestHostIdPrefName);

  if (pending_host_id_from_prefs == kNoPendingRequest) {
    PA_LOG(ERROR) << "HostBackendDelegateImpl::GetPendingHostRequest(): Tried "
                  << "to get pending host request, but there was no pending "
                  << "host request.";
    NOTREACHED();
  }

  if (pending_host_id_from_prefs == kPendingRemovalOfCurrentHost)
    return base::nullopt;

  for (const auto& remote_device : device_sync_client_->GetSyncedDevices()) {
    if (pending_host_id_from_prefs == remote_device.GetDeviceId())
      return remote_device;
  }

  PA_LOG(ERROR) << "HostBackendDelegateImpl::GetPendingHostRequest(): Tried to "
                << "get pending host request, but the pending host ID was not "
                << "present.";
  NOTREACHED();
  return base::nullopt;
}

base::Optional<multidevice::RemoteDeviceRef>
HostBackendDelegateImpl::GetMultiDeviceHostFromBackend() const {
  return host_from_last_sync_;
}

bool HostBackendDelegateImpl::IsHostEligible(
    const multidevice::RemoteDeviceRef& provided_host) {
  return base::ContainsValue(
      eligible_host_devices_provider_->GetEligibleHostDevices(), provided_host);
}

void HostBackendDelegateImpl::SetPendingHostRequest(
    const std::string& pending_host_id) {
  const std::string host_id_from_prefs_before_call =
      pref_service_->GetString(kPendingRequestHostIdPrefName);
  if (pending_host_id == host_id_from_prefs_before_call)
    return;

  pref_service_->SetString(kPendingRequestHostIdPrefName, pending_host_id);
  timer_->Stop();
  NotifyPendingHostRequestChange();
}

void HostBackendDelegateImpl::AttemptNetworkRequest(bool is_retry) {
  if (!HasPendingHostRequest()) {
    PA_LOG(ERROR) << "HostBackendDelegateImpl::AttemptNetworkRequest(): Tried "
                  << "to attempt a network request, but there was no pending "
                  << "host request.";
    NOTREACHED();
  }

  base::Optional<multidevice::RemoteDeviceRef> pending_host_request =
      GetPendingHostRequest();

  // If |pending_host_request| is non-null, the request should be to set that
  // device. If it is null, the pending request is to remove the current host.
  multidevice::RemoteDeviceRef device_to_set =
      pending_host_request ? *pending_host_request : *host_from_last_sync_;

  // Likewise, if |pending_host_request| is non-null, that device should be
  // enabled, and if it is null, the old device should be disabled.
  bool should_enable = pending_host_request != base::nullopt;

  PA_LOG(INFO) << "HostBackendDelegateImpl::AttemptNetworkRequest(): "
               << (is_retry ? "Retrying attempt" : "Attempting") << " to "
               << (should_enable ? "enable" : "disable") << " the host with ID "
               << device_to_set.GetTruncatedDeviceIdForLogs() << ".";

  device_sync_client_->SetSoftwareFeatureState(
      device_to_set.public_key(),
      multidevice::SoftwareFeature::kBetterTogetherHost,
      should_enable /* enabled */, should_enable /* is_exclusive */,
      base::BindOnce(&HostBackendDelegateImpl::OnSetSoftwareFeatureStateResult,
                     weak_ptr_factory_.GetWeakPtr(), device_to_set,
                     should_enable));
}

void HostBackendDelegateImpl::OnNewDevicesSynced() {
  base::Optional<multidevice::RemoteDeviceRef> host_from_sync =
      GetHostFromDeviceSync();
  if (host_from_last_sync_ == host_from_sync)
    return;

  std::string old_host_id =
      host_from_last_sync_ ? host_from_last_sync_->GetTruncatedDeviceIdForLogs()
                           : kNoHostForLogging;
  std::string new_host_id = host_from_sync
                                ? host_from_sync->GetTruncatedDeviceIdForLogs()
                                : kNoHostForLogging;

  host_from_last_sync_ = host_from_sync;
  PA_LOG(VERBOSE) << "HostBackendDelegateImpl::OnNewDevicesSynced(): New host "
                  << "device has been set. Old host device ID: " << old_host_id
                  << ", New host device ID: " << new_host_id;

  // If there is a pending request and the new host fulfills that pending
  // request, there is no longer a pending request.
  if (HasPendingHostRequest() &&
      host_from_last_sync_ == GetPendingHostRequest()) {
    SetPendingHostRequest(kNoPendingRequest);
  }

  NotifyHostChangedOnBackend();
}

base::Optional<multidevice::RemoteDeviceRef>
HostBackendDelegateImpl::GetHostFromDeviceSync() {
  multidevice::RemoteDeviceRefList synced_devices =
      device_sync_client_->GetSyncedDevices();
  auto it = std::find_if(
      synced_devices.begin(), synced_devices.end(),
      [](const auto& remote_device) {
        multidevice::SoftwareFeatureState host_state =
            remote_device.GetSoftwareFeatureState(
                multidevice::SoftwareFeature::kBetterTogetherHost);
        return host_state == multidevice::SoftwareFeatureState::kEnabled;
      });

  if (it == synced_devices.end())
    return base::nullopt;

  return *it;
}

void HostBackendDelegateImpl::OnSetSoftwareFeatureStateResult(
    multidevice::RemoteDeviceRef device_for_request,
    bool attempted_to_enable,
    device_sync::mojom::NetworkRequestResult result_code) {
  bool success =
      result_code == device_sync::mojom::NetworkRequestResult::kSuccess;

  std::stringstream ss;
  ss << "HostBackendDelegateImpl::OnSetSoftwareFeatureStateResult(): "
     << (success ? "Completed successful" : "Failure requesting") << " "
     << "host change. Device ID: "
     << device_for_request.GetTruncatedDeviceIdForLogs()
     << ", Attempted to enable: " << (attempted_to_enable ? "true" : "false");

  if (success) {
    PA_LOG(VERBOSE) << ss.str();
    return;
  }

  ss << ", Error code: " << result_code;
  PA_LOG(WARNING) << ss.str();

  if (!HasPendingHostRequest())
    return;

  base::Optional<multidevice::RemoteDeviceRef> pending_host_request =
      GetPendingHostRequest();

  bool failed_request_was_to_set_pending_host =
      attempted_to_enable && pending_host_request &&
      *pending_host_request == device_for_request;

  bool failed_request_was_to_remove_pending_host =
      !attempted_to_enable && !pending_host_request &&
      device_for_request == host_from_last_sync_;

  // If the request which failed corresponds to the most recent call to
  // AttemptToSetMultiDeviceHostOnBackend(), alert observers that this request
  // failed and schedule a retry.
  if (failed_request_was_to_set_pending_host ||
      failed_request_was_to_remove_pending_host) {
    NotifyBackendRequestFailed();
    timer_->Start(FROM_HERE,
                  base::TimeDelta::FromMinutes(kNumMinutesBetweenRetries),
                  base::Bind(&HostBackendDelegateImpl::AttemptNetworkRequest,
                             base::Unretained(this), true /* is_retry */));
  }
}

}  // namespace multidevice_setup

}  // namespace chromeos
