// Copyright (c) 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 "quiche/quic/core/quic_network_blackhole_detector.h"

#include "quiche/quic/core/quic_constants.h"

namespace quic {

namespace {

class AlarmDelegate : public QuicAlarm::DelegateWithContext {
 public:
  explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector,
                         QuicConnectionContext* context)
      : QuicAlarm::DelegateWithContext(context), detector_(detector) {}
  AlarmDelegate(const AlarmDelegate&) = delete;
  AlarmDelegate& operator=(const AlarmDelegate&) = delete;

  void OnAlarm() override { detector_->OnAlarm(); }

 private:
  QuicNetworkBlackholeDetector* detector_;
};

}  // namespace

QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
    Delegate* delegate, QuicConnectionArena* arena,
    QuicAlarmFactory* alarm_factory, QuicConnectionContext* context)
    : delegate_(delegate),
      alarm_(alarm_factory->CreateAlarm(
          arena->New<AlarmDelegate>(this, context), arena)) {}

void QuicNetworkBlackholeDetector::OnAlarm() {
  QuicTime next_deadline = GetEarliestDeadline();
  if (!next_deadline.IsInitialized()) {
    QUIC_BUG(quic_bug_10328_1) << "BlackholeDetector alarm fired unexpectedly";
    return;
  }

  QUIC_DVLOG(1) << "BlackholeDetector alarm firing. next_deadline:"
                << next_deadline
                << ", path_degrading_deadline_:" << path_degrading_deadline_
                << ", path_mtu_reduction_deadline_:"
                << path_mtu_reduction_deadline_
                << ", blackhole_deadline_:" << blackhole_deadline_;
  if (path_degrading_deadline_ == next_deadline) {
    path_degrading_deadline_ = QuicTime::Zero();
    delegate_->OnPathDegradingDetected();
  }

  if (path_mtu_reduction_deadline_ == next_deadline) {
    path_mtu_reduction_deadline_ = QuicTime::Zero();
    delegate_->OnPathMtuReductionDetected();
  }

  if (blackhole_deadline_ == next_deadline) {
    blackhole_deadline_ = QuicTime::Zero();
    delegate_->OnBlackholeDetected();
  }

  UpdateAlarm();
}

void QuicNetworkBlackholeDetector::StopDetection(bool permanent) {
  if (permanent) {
    alarm_->PermanentCancel();
  } else {
    alarm_->Cancel();
  }
  path_degrading_deadline_ = QuicTime::Zero();
  blackhole_deadline_ = QuicTime::Zero();
  path_mtu_reduction_deadline_ = QuicTime::Zero();
}

void QuicNetworkBlackholeDetector::RestartDetection(
    QuicTime path_degrading_deadline, QuicTime blackhole_deadline,
    QuicTime path_mtu_reduction_deadline) {
  path_degrading_deadline_ = path_degrading_deadline;
  blackhole_deadline_ = blackhole_deadline;
  path_mtu_reduction_deadline_ = path_mtu_reduction_deadline;

  QUIC_BUG_IF(quic_bug_12708_1, blackhole_deadline_.IsInitialized() &&
                                    blackhole_deadline_ != GetLastDeadline())
      << "Blackhole detection deadline should be the last deadline.";

  UpdateAlarm();
}

QuicTime QuicNetworkBlackholeDetector::GetEarliestDeadline() const {
  QuicTime result = QuicTime::Zero();
  for (QuicTime t : {path_degrading_deadline_, blackhole_deadline_,
                     path_mtu_reduction_deadline_}) {
    if (!t.IsInitialized()) {
      continue;
    }

    if (!result.IsInitialized() || t < result) {
      result = t;
    }
  }

  return result;
}

QuicTime QuicNetworkBlackholeDetector::GetLastDeadline() const {
  return std::max({path_degrading_deadline_, blackhole_deadline_,
                   path_mtu_reduction_deadline_});
}

void QuicNetworkBlackholeDetector::UpdateAlarm() const {
  // If called after OnBlackholeDetected(), the alarm may have been permanently
  // cancelled and is not safe to be armed again.
  if (alarm_->IsPermanentlyCancelled()) {
    return;
  }

  QuicTime next_deadline = GetEarliestDeadline();

  QUIC_DVLOG(1) << "Updating alarm. next_deadline:" << next_deadline
                << ", path_degrading_deadline_:" << path_degrading_deadline_
                << ", path_mtu_reduction_deadline_:"
                << path_mtu_reduction_deadline_
                << ", blackhole_deadline_:" << blackhole_deadline_;

  alarm_->Update(next_deadline, kAlarmGranularity);
}

bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
  return alarm_->IsSet();
}

}  // namespace quic
