// Copyright 2013 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 "quic/core/quic_alarm.h"

#include "quic/platform/api/quic_bug_tracker.h"
#include "quic/platform/api/quic_flag_utils.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_stack_trace.h"

namespace quic {

QuicAlarm::QuicAlarm(QuicArenaScopedPtr<Delegate> delegate)
    : delegate_(std::move(delegate)), deadline_(QuicTime::Zero()) {}

QuicAlarm::~QuicAlarm() {
  if (GetQuicRestartFlag(quic_alarm_add_permanent_cancel) && IsSet()) {
    QUIC_CODE_COUNT(quic_alarm_not_cancelled_in_dtor);
    static uint64_t hit_count = 0;
    ++hit_count;
    if ((hit_count & (hit_count - 1)) == 0) {
      QUIC_LOG(ERROR) << "QuicAlarm not cancelled at destruction. "
                      << QuicStackTrace();
    }
  }
}

void QuicAlarm::Set(QuicTime new_deadline) {
  QUICHE_DCHECK(!IsSet());
  QUICHE_DCHECK(new_deadline.IsInitialized());

  if (IsPermanentlyCancelled()) {
    QUIC_BUG(quic_alarm_illegal_set)
        << "Set called after alarm is permanently cancelled. new_deadline:"
        << new_deadline;
    return;
  }

  deadline_ = new_deadline;
  SetImpl();
}

void QuicAlarm::CancelInternal(bool permanent) {
  if (!GetQuicRestartFlag(quic_alarm_add_permanent_cancel)) {
    if (!IsSet()) {
      // Don't try to cancel an alarm that hasn't been set.
      return;
    }
    deadline_ = QuicTime::Zero();
    CancelImpl();
    return;
  }

  if (IsSet()) {
    deadline_ = QuicTime::Zero();
    CancelImpl();
  }

  if (permanent) {
    delegate_.reset();
  }
}

bool QuicAlarm::IsPermanentlyCancelled() const { return delegate_ == nullptr; }

void QuicAlarm::Update(QuicTime new_deadline, QuicTime::Delta granularity) {
  if (IsPermanentlyCancelled()) {
    QUIC_BUG(quic_alarm_illegal_update)
        << "Update called after alarm is permanently cancelled. new_deadline:"
        << new_deadline << ", granularity:" << granularity;
    return;
  }

  if (!new_deadline.IsInitialized()) {
    Cancel();
    return;
  }
  if (std::abs((new_deadline - deadline_).ToMicroseconds()) <
      granularity.ToMicroseconds()) {
    return;
  }
  const bool was_set = IsSet();
  deadline_ = new_deadline;
  if (was_set) {
    UpdateImpl();
  } else {
    SetImpl();
  }
}

bool QuicAlarm::IsSet() const {
  return deadline_.IsInitialized();
}

void QuicAlarm::Fire() {
  if (!IsSet()) {
    return;
  }

  deadline_ = QuicTime::Zero();
  if (!IsPermanentlyCancelled()) {
    absl::optional<QuicConnectionContextSwitcher> context_switcher;
    if (GetQuicReloadableFlag(quic_restore_connection_context_in_alarms)) {
      QUIC_RELOADABLE_FLAG_COUNT(quic_restore_connection_context_in_alarms);
      context_switcher.emplace(delegate_->GetConnectionContext());
    }
    delegate_->OnAlarm();
  }
}

void QuicAlarm::UpdateImpl() {
  // CancelImpl and SetImpl take the new deadline by way of the deadline_
  // member, so save and restore deadline_ before canceling.
  const QuicTime new_deadline = deadline_;

  deadline_ = QuicTime::Zero();
  CancelImpl();

  deadline_ = new_deadline;
  SetImpl();
}

}  // namespace quic
