// Copyright 2019 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 "chrome/browser/sharing/sharing_device_source_sync.h"

#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "base/callback.h"
#include "base/containers/cxx20_erase.h"
#include "base/stl_util.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "chrome/browser/sharing/features.h"
#include "chrome/browser/sharing/proto/sharing_message.pb.h"
#include "chrome/browser/sharing/sharing_constants.h"
#include "chrome/browser/sharing/sharing_utils.h"
#include "components/send_tab_to_self/target_device_info.h"
#include "components/sync/driver/sync_service.h"
#include "components/sync_device_info/device_info.h"
#include "components/sync_device_info/local_device_info_provider.h"
#include "components/sync_device_info/local_device_info_util.h"
#include "content/public/browser/browser_task_traits.h"

using sync_pb::SharingSpecificFields;

namespace {
bool IsDesktop(sync_pb::SyncEnums::DeviceType type) {
  switch (type) {
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_CROS:
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_LINUX:
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_MAC:
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_WIN:
      return true;
    case sync_pb::SyncEnums_DeviceType_TYPE_PHONE:
    case sync_pb::SyncEnums_DeviceType_TYPE_TABLET:
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_UNSET:
    case sync_pb::SyncEnums::DeviceType::SyncEnums_DeviceType_TYPE_OTHER:
      return false;
  }
}

bool IsStale(const syncer::DeviceInfo& device) {
  if (base::FeatureList::IsEnabled(kSharingMatchPulseInterval)) {
    base::TimeDelta pulse_delta = base::Hours(
        IsDesktop(device.device_type()) ? kSharingPulseDeltaDesktopHours.Get()
                                        : kSharingPulseDeltaAndroidHours.Get());
    base::Time min_updated_time =
        base::Time::Now() - device.pulse_interval() - pulse_delta;
    return device.last_updated_timestamp() < min_updated_time;
  }

  const base::Time min_updated_time =
      base::Time::Now() - kSharingDeviceExpiration;
  return device.last_updated_timestamp() < min_updated_time;
}
}  // namespace

SharingDeviceSourceSync::SharingDeviceSourceSync(
    syncer::SyncService* sync_service,
    syncer::LocalDeviceInfoProvider* local_device_info_provider,
    syncer::DeviceInfoTracker* device_info_tracker)
    : sync_service_(sync_service),
      local_device_info_provider_(local_device_info_provider),
      device_info_tracker_(device_info_tracker) {
  base::ThreadPool::PostTaskAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
      base::BindOnce(syncer::GetPersonalizableDeviceNameBlocking),
      base::BindOnce(
          &SharingDeviceSourceSync::InitPersonalizableLocalDeviceName,
          weak_ptr_factory_.GetWeakPtr()));

  if (!device_info_tracker_->IsSyncing())
    device_info_tracker_->AddObserver(this);

  if (!local_device_info_provider_->GetLocalDeviceInfo()) {
    local_device_info_ready_subscription_ =
        local_device_info_provider_->RegisterOnInitializedCallback(
            base::BindRepeating(
                &SharingDeviceSourceSync::OnLocalDeviceInfoProviderReady,
                weak_ptr_factory_.GetWeakPtr()));
  }
}

SharingDeviceSourceSync::~SharingDeviceSourceSync() {
  device_info_tracker_->RemoveObserver(this);
}

std::unique_ptr<syncer::DeviceInfo> SharingDeviceSourceSync::GetDeviceByGuid(
    const std::string& guid) {
  if (!IsSyncEnabledForSharing(sync_service_))
    return nullptr;

  std::unique_ptr<syncer::DeviceInfo> device_info =
      device_info_tracker_->GetDeviceInfo(guid);
  if (!device_info)
    return nullptr;

  device_info->set_client_name(
      send_tab_to_self::GetSharingDeviceNames(device_info.get()).full_name);
  return device_info;
}

std::vector<std::unique_ptr<syncer::DeviceInfo>>
SharingDeviceSourceSync::GetDeviceCandidates(
    SharingSpecificFields::EnabledFeatures required_feature) {
  if (!IsSyncEnabledForSharing(sync_service_) || !IsReady())
    return {};

  return RenameAndDeduplicateDevices(FilterDeviceCandidates(
      device_info_tracker_->GetAllDeviceInfo(), required_feature));
}

bool SharingDeviceSourceSync::IsReady() {
  return IsSyncDisabledForSharing(sync_service_) ||
         (personalizable_local_device_name_ &&
          device_info_tracker_->IsSyncing() &&
          local_device_info_provider_->GetLocalDeviceInfo());
}

void SharingDeviceSourceSync::OnDeviceInfoChange() {
  if (device_info_tracker_->IsSyncing())
    device_info_tracker_->RemoveObserver(this);
  MaybeRunReadyCallbacks();
}

void SharingDeviceSourceSync::SetDeviceInfoTrackerForTesting(
    syncer::DeviceInfoTracker* tracker) {
  device_info_tracker_->RemoveObserver(this);
  device_info_tracker_ = tracker;
  if (!device_info_tracker_->IsSyncing())
    device_info_tracker_->AddObserver(this);
  MaybeRunReadyCallbacks();
}

void SharingDeviceSourceSync::InitPersonalizableLocalDeviceName(
    std::string personalizable_local_device_name) {
  personalizable_local_device_name_ =
      std::move(personalizable_local_device_name);
  MaybeRunReadyCallbacks();
}

void SharingDeviceSourceSync::OnLocalDeviceInfoProviderReady() {
  DCHECK(local_device_info_provider_->GetLocalDeviceInfo());
  local_device_info_ready_subscription_ = {};
  MaybeRunReadyCallbacks();
}

std::vector<std::unique_ptr<syncer::DeviceInfo>>
SharingDeviceSourceSync::FilterDeviceCandidates(
    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices,
    sync_pb::SharingSpecificFields::EnabledFeatures required_feature) const {
  std::set<SharingSpecificFields::EnabledFeatures> accepted_features{
      required_feature};
  if (required_feature == SharingSpecificFields::CLICK_TO_CALL_V2) {
    accepted_features.insert(SharingSpecificFields::CLICK_TO_CALL_VAPID);
  }
  if (required_feature == SharingSpecificFields::SHARED_CLIPBOARD_V2) {
    accepted_features.insert(SharingSpecificFields::SHARED_CLIPBOARD_VAPID);
  }

  bool can_send_via_vapid = CanSendViaVapid(sync_service_);
  bool can_send_via_sender_id = CanSendViaSenderID(sync_service_);

  base::EraseIf(devices, [accepted_features, can_send_via_vapid,
                          can_send_via_sender_id](const auto& device) {
    // Checks if |last_updated_timestamp| is not too old.
    if (IsStale(*device.get()))
      return true;

    // Checks if device has SharingInfo.
    if (!device->sharing_info())
      return true;

    // Checks if message can be sent via either VAPID or sender ID.
    auto& vapid_target_info = device->sharing_info()->vapid_target_info;
    auto& sender_id_target_info = device->sharing_info()->sender_id_target_info;
    bool vapid_channel_valid =
        (can_send_via_vapid && !vapid_target_info.fcm_token.empty() &&
         !vapid_target_info.p256dh.empty() &&
         !vapid_target_info.auth_secret.empty());
    bool sender_id_channel_valid =
        (can_send_via_sender_id && !sender_id_target_info.fcm_token.empty() &&
         !sender_id_target_info.p256dh.empty() &&
         !sender_id_target_info.auth_secret.empty());
    if (!vapid_channel_valid && !sender_id_channel_valid)
      return true;

    // Checks whether |device| supports any of |accepted_features|.
    return base::STLSetIntersection<
               std::vector<SharingSpecificFields::EnabledFeatures>>(
               device->sharing_info()->enabled_features, accepted_features)
        .empty();
  });
  return devices;
}

std::vector<std::unique_ptr<syncer::DeviceInfo>>
SharingDeviceSourceSync::RenameAndDeduplicateDevices(
    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices) const {
  // Sort the devices so the most recently modified devices are first.
  std::sort(devices.begin(), devices.end(),
            [](const auto& device1, const auto& device2) {
              return device1->last_updated_timestamp() >
                     device2->last_updated_timestamp();
            });

  std::unordered_map<syncer::DeviceInfo*, send_tab_to_self::SharingDeviceNames>
      device_names_map;
  std::unordered_set<std::string> full_names;
  std::unordered_map<std::string, int> short_names_counter;

  // To prevent adding candidates with same full name as local device.
  full_names.insert(send_tab_to_self::GetSharingDeviceNames(
                        local_device_info_provider_->GetLocalDeviceInfo())
                        .full_name);
  // To prevent M78- instances of Chrome with same device model from showing up.
  full_names.insert(*personalizable_local_device_name_);

  for (const auto& device : devices) {
    send_tab_to_self::SharingDeviceNames device_names =
        send_tab_to_self::GetSharingDeviceNames(device.get());

    // Only insert the first occurrence of each device name.
    auto inserted = full_names.insert(device_names.full_name);
    if (!inserted.second)
      continue;

    short_names_counter[device_names.short_name]++;
    device_names_map.insert({device.get(), std::move(device_names)});
  }

  // Filter duplicates and rename devices.
  base::EraseIf(devices, [&device_names_map,
                          &short_names_counter](auto& device) {
    auto it = device_names_map.find(device.get());
    if (it == device_names_map.end())
      return true;

    const send_tab_to_self::SharingDeviceNames& device_names = it->second;
    bool unique_short_name = short_names_counter[device_names.short_name] == 1;
    device->set_client_name(unique_short_name ? device_names.short_name
                                              : device_names.full_name);
    return false;
  });

  return devices;
}
