// Copyright 2020 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 "cast/sender/cast_app_discovery_service_impl.h"

#include <algorithm>
#include <chrono>
#include <utility>

#include "cast/sender/public/cast_media_source.h"
#include "util/osp_logging.h"

namespace openscreen {
namespace cast {
namespace {

// The minimum time that must elapse before an app availability result can be
// force refreshed.
static constexpr std::chrono::minutes kRefreshThreshold =
    std::chrono::minutes(1);

}  // namespace

CastAppDiscoveryServiceImpl::CastAppDiscoveryServiceImpl(
    CastPlatformClient* platform_client,
    ClockNowFunctionPtr clock)
    : platform_client_(platform_client), clock_(clock), weak_factory_(this) {
  OSP_DCHECK(platform_client_);
  OSP_DCHECK(clock_);
}

CastAppDiscoveryServiceImpl::~CastAppDiscoveryServiceImpl() {
  OSP_CHECK_EQ(avail_queries_.size(), 0u);
}

CastAppDiscoveryService::Subscription
CastAppDiscoveryServiceImpl::StartObservingAvailability(
    const CastMediaSource& source,
    AvailabilityCallback callback) {
  const std::string& source_id = source.source_id();

  // Return cached results immediately, if available.
  std::vector<std::string> cached_device_ids =
      availability_tracker_.GetAvailableDevices(source);
  if (!cached_device_ids.empty()) {
    callback(source, GetReceiversByIds(cached_device_ids));
  }

  auto& callbacks = avail_queries_[source_id];
  uint32_t query_id = next_avail_query_id_++;
  callbacks.push_back({query_id, std::move(callback)});
  if (callbacks.size() == 1) {
    // NOTE: Even though we retain availability results for an app unregistered
    // from the tracker, we will refresh the results when the app is
    // re-registered.
    std::vector<std::string> new_app_ids =
        availability_tracker_.RegisterSource(source);
    for (const auto& app_id : new_app_ids) {
      for (const auto& entry : receivers_by_id_) {
        RequestAppAvailability(entry.first, app_id);
      }
    }
  }

  return Subscription(this, query_id);
}

void CastAppDiscoveryServiceImpl::Refresh() {
  const auto app_ids = availability_tracker_.GetRegisteredApps();
  for (const auto& entry : receivers_by_id_) {
    for (const auto& app_id : app_ids) {
      RequestAppAvailability(entry.first, app_id);
    }
  }
}

void CastAppDiscoveryServiceImpl::AddOrUpdateReceiver(
    const ServiceInfo& receiver) {
  const std::string& device_id = receiver.unique_id;
  receivers_by_id_[device_id] = receiver;

  // Any queries that currently contain this receiver should be updated.
  UpdateAvailabilityQueries(
      availability_tracker_.GetSupportedSources(device_id));

  for (const std::string& app_id : availability_tracker_.GetRegisteredApps()) {
    RequestAppAvailability(device_id, app_id);
  }
}

void CastAppDiscoveryServiceImpl::RemoveReceiver(const ServiceInfo& receiver) {
  const std::string& device_id = receiver.unique_id;
  receivers_by_id_.erase(device_id);
  UpdateAvailabilityQueries(
      availability_tracker_.RemoveResultsForDevice(device_id));
}

void CastAppDiscoveryServiceImpl::RequestAppAvailability(
    const std::string& device_id,
    const std::string& app_id) {
  if (ShouldRefreshAppAvailability(device_id, app_id, clock_())) {
    platform_client_->RequestAppAvailability(
        device_id, app_id,
        [self = weak_factory_.GetWeakPtr(), device_id](
            const std::string& app_id, AppAvailabilityResult availability) {
          if (self) {
            self->UpdateAppAvailability(device_id, app_id, availability);
          }
        });
  }
}

void CastAppDiscoveryServiceImpl::UpdateAppAvailability(
    const std::string& device_id,
    const std::string& app_id,
    AppAvailabilityResult availability) {
  if (receivers_by_id_.find(device_id) == receivers_by_id_.end()) {
    return;
  }

  OSP_DVLOG << "App " << app_id << " on receiver " << device_id << " is "
            << ToString(availability);

  UpdateAvailabilityQueries(availability_tracker_.UpdateAppAvailability(
      device_id, app_id, {availability, clock_()}));
}

void CastAppDiscoveryServiceImpl::UpdateAvailabilityQueries(
    const std::vector<CastMediaSource>& sources) {
  for (const auto& source : sources) {
    const std::string& source_id = source.source_id();
    auto it = avail_queries_.find(source_id);
    if (it == avail_queries_.end())
      continue;
    std::vector<std::string> device_ids =
        availability_tracker_.GetAvailableDevices(source);
    std::vector<ServiceInfo> receivers = GetReceiversByIds(device_ids);
    for (const auto& callback : it->second) {
      callback.callback(source, receivers);
    }
  }
}

std::vector<ServiceInfo> CastAppDiscoveryServiceImpl::GetReceiversByIds(
    const std::vector<std::string>& device_ids) const {
  std::vector<ServiceInfo> receivers;
  for (const std::string& device_id : device_ids) {
    auto entry = receivers_by_id_.find(device_id);
    if (entry != receivers_by_id_.end()) {
      receivers.push_back(entry->second);
    }
  }
  return receivers;
}

bool CastAppDiscoveryServiceImpl::ShouldRefreshAppAvailability(
    const std::string& device_id,
    const std::string& app_id,
    Clock::time_point now) const {
  // TODO(btolsch): Consider an exponential backoff mechanism instead.
  // Receivers will typically respond with "unavailable" immediately after boot
  // and then become available 10-30 seconds later.
  auto availability = availability_tracker_.GetAvailability(device_id, app_id);
  switch (availability.availability) {
    case AppAvailabilityResult::kAvailable:
      return false;
    case AppAvailabilityResult::kUnavailable:
      return (now - availability.time) > kRefreshThreshold;
    // TODO(btolsch): Should there be a background task for periodically
    // refreshing kUnknown (or even kUnavailable) results?
    case AppAvailabilityResult::kUnknown:
      return true;
  }

  OSP_NOTREACHED();
}

void CastAppDiscoveryServiceImpl::RemoveAvailabilityCallback(uint32_t id) {
  for (auto entry = avail_queries_.begin(); entry != avail_queries_.end();
       ++entry) {
    const std::string& source_id = entry->first;
    auto& callbacks = entry->second;
    auto it =
        std::find_if(callbacks.begin(), callbacks.end(),
                     [id](const AvailabilityCallbackEntry& callback_entry) {
                       return callback_entry.id == id;
                     });
    if (it != callbacks.end()) {
      callbacks.erase(it);
      if (callbacks.empty()) {
        availability_tracker_.UnregisterSource(source_id);
        avail_queries_.erase(entry);
      }
      return;
    }
  }
}

}  // namespace cast
}  // namespace openscreen
