/*
 *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "call/adaptation/resource_adaptation_processor.h"

#include <limits>
#include <utility>

#include "rtc_base/checks.h"

namespace webrtc {

namespace {

ResourceConsumerConfiguration* FindMostPreferredConfiguration(
    const std::vector<ResourceConsumerConfiguration*>& configurations) {
  if (configurations.empty())
    return nullptr;
  ResourceConsumerConfiguration* most_preferred_configuration =
      configurations[0];
  double most_preferred_configuration_preference =
      most_preferred_configuration->Preference();
  RTC_DCHECK_GE(most_preferred_configuration_preference, 0.0);
  for (size_t i = 1; i < configurations.size(); ++i) {
    auto* configuration = configurations[i];
    double preference = configuration->Preference();
    RTC_DCHECK_GE(preference, 0.0);
    if (most_preferred_configuration_preference < preference) {
      most_preferred_configuration = configuration;
      most_preferred_configuration_preference = preference;
    }
  }
  return most_preferred_configuration;
}

}  // namespace

ConsumerConfigurationPair::ConsumerConfigurationPair(
    ResourceConsumer* consumer,
    ResourceConsumerConfiguration* configuration)
    : consumer(consumer), configuration(configuration) {}

absl::optional<ConsumerConfigurationPair>
ResourceAdaptationProcessor::FindNextConfiguration() {
  ResourceUsageState overall_usage = ResourceUsageState::kUnderuse;
  for (auto& resource : resources_) {
    ResourceUsageState resource_usage = resource->CurrentUsageState();
    if (resource_usage == ResourceUsageState::kStable) {
      // If any resource is "stable", we are not underusing.
      if (overall_usage == ResourceUsageState::kUnderuse)
        overall_usage = ResourceUsageState::kStable;
    } else if (resource_usage == ResourceUsageState::kOveruse) {
      // If any resource is "overuse", we are overusing.
      overall_usage = ResourceUsageState::kOveruse;
      break;
    }
  }
  // If we are stable we should neither adapt up or down: stay where we are.
  if (overall_usage == ResourceUsageState::kStable)
    return absl::nullopt;
  if (overall_usage == ResourceUsageState::kOveruse) {
    // If we are overusing, we adapt down the most expensive consumer to its
    // most preferred lower neighbor.
    ResourceConsumer* max_cost_consumer =
        FindMostExpensiveConsumerThatCanBeAdaptedDown();
    if (!max_cost_consumer)
      return absl::nullopt;
    ResourceConsumerConfiguration* next_configuration =
        FindMostPreferredConfiguration(
            max_cost_consumer->configuration()->lower_neighbors());
    RTC_DCHECK(next_configuration);
    return ConsumerConfigurationPair(max_cost_consumer, next_configuration);
  } else {
    RTC_DCHECK_EQ(overall_usage, ResourceUsageState::kUnderuse);
    // If we are underusing, we adapt up the least expensive consumer to its
    // most preferred upper neighbor.
    ResourceConsumer* min_cost_consumer =
        FindLeastExpensiveConsumerThatCanBeAdaptedUp();
    if (!min_cost_consumer)
      return absl::nullopt;
    ResourceConsumerConfiguration* next_configuration =
        FindMostPreferredConfiguration(
            min_cost_consumer->configuration()->upper_neighbors());
    RTC_DCHECK(next_configuration);
    return ConsumerConfigurationPair(min_cost_consumer, next_configuration);
  }
}

ResourceConsumer*
ResourceAdaptationProcessor::FindMostExpensiveConsumerThatCanBeAdaptedDown() {
  ResourceConsumer* max_cost_consumer = nullptr;
  double max_cost = -1.0;
  for (auto& consumer : consumers_) {
    if (consumer->configuration()->lower_neighbors().empty())
      continue;
    double cost = consumer->configuration()->Cost();
    if (max_cost < cost) {
      max_cost_consumer = consumer.get();
      max_cost = cost;
    }
  }
  return max_cost_consumer;
}

ResourceConsumer*
ResourceAdaptationProcessor::FindLeastExpensiveConsumerThatCanBeAdaptedUp() {
  ResourceConsumer* min_cost_consumer = nullptr;
  double min_cost = std::numeric_limits<double>::infinity();
  for (auto& consumer : consumers_) {
    if (consumer->configuration()->upper_neighbors().empty())
      continue;
    double cost = consumer->configuration()->Cost();
    if (min_cost > cost) {
      min_cost_consumer = consumer.get();
      min_cost = cost;
    }
  }
  return min_cost_consumer;
}

}  // namespace webrtc
