/*
 *  Copyright 2018 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 "p2p/base/regathering_controller.h"
#include "rtc_base/task_utils/to_queued_task.h"

namespace webrtc {

BasicRegatheringController::BasicRegatheringController(
    const Config& config,
    cricket::IceTransportInternal* ice_transport,
    rtc::Thread* thread)
    : config_(config), ice_transport_(ice_transport), thread_(thread) {
  RTC_DCHECK(thread_);
  RTC_DCHECK_RUN_ON(thread_);
  RTC_DCHECK(ice_transport_);
  ice_transport_->SignalStateChanged.connect(
      this, &BasicRegatheringController::OnIceTransportStateChanged);
  ice_transport->SignalWritableState.connect(
      this, &BasicRegatheringController::OnIceTransportWritableState);
  ice_transport->SignalReceivingState.connect(
      this, &BasicRegatheringController::OnIceTransportReceivingState);
  ice_transport->SignalNetworkRouteChanged.connect(
      this, &BasicRegatheringController::OnIceTransportNetworkRouteChanged);
}

BasicRegatheringController::~BasicRegatheringController() {
  RTC_DCHECK_RUN_ON(thread_);
}

void BasicRegatheringController::Start() {
  RTC_DCHECK_RUN_ON(thread_);
  ScheduleRecurringRegatheringOnFailedNetworks();
}

void BasicRegatheringController::SetConfig(const Config& config) {
  RTC_DCHECK_RUN_ON(thread_);
  bool need_reschedule_on_failed_networks =
      pending_regathering_ && (config_.regather_on_failed_networks_interval !=
                               config.regather_on_failed_networks_interval);
  config_ = config;
  if (need_reschedule_on_failed_networks) {
    ScheduleRecurringRegatheringOnFailedNetworks();
  }
}

void BasicRegatheringController::
    ScheduleRecurringRegatheringOnFailedNetworks() {
  RTC_DCHECK_RUN_ON(thread_);
  RTC_DCHECK(config_.regather_on_failed_networks_interval >= 0);
  // Reset pending_regathering_ to cancel any potentially pending tasks.
  pending_regathering_.reset(new ScopedTaskSafety());

  thread_->PostDelayedTask(
      ToQueuedTask(*pending_regathering_.get(),
                   [this]() {
                     RTC_DCHECK_RUN_ON(thread_);
                     // Only regather when the current session is in the CLEARED
                     // state (i.e., not running or stopped). It is only
                     // possible to enter this state when we gather continually,
                     // so there is an implicit check on continual gathering
                     // here.
                     if (allocator_session_ &&
                         allocator_session_->IsCleared()) {
                       allocator_session_->RegatherOnFailedNetworks();
                     }
                     ScheduleRecurringRegatheringOnFailedNetworks();
                   }),
      config_.regather_on_failed_networks_interval);
}

}  // namespace webrtc
