/*
 *  Copyright (c) 2021 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 "net/dcsctp/socket/heartbeat_handler.h"

#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <utility>
#include <vector>

#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "net/dcsctp/packet/bounded_byte_reader.h"
#include "net/dcsctp/packet/bounded_byte_writer.h"
#include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h"
#include "net/dcsctp/packet/chunk/heartbeat_request_chunk.h"
#include "net/dcsctp/packet/parameter/heartbeat_info_parameter.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/sctp_packet.h"
#include "net/dcsctp/public/dcsctp_options.h"
#include "net/dcsctp/public/dcsctp_socket.h"
#include "net/dcsctp/socket/context.h"
#include "net/dcsctp/timer/timer.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace dcsctp {
using ::webrtc::TimeDelta;
using ::webrtc::Timestamp;

// This is stored (in serialized form) as HeartbeatInfoParameter sent in
// HeartbeatRequestChunk and received back in HeartbeatAckChunk. It should be
// well understood that this data may be modified by the peer, so it can't
// be trusted.
//
// It currently only stores a timestamp, in millisecond precision, to allow for
// RTT measurements. If that would be manipulated by the peer, it would just
// result in incorrect RTT measurements, which isn't an issue.
class HeartbeatInfo {
 public:
  static constexpr size_t kBufferSize = sizeof(uint64_t);
  static_assert(kBufferSize == 8, "Unexpected buffer size");

  explicit HeartbeatInfo(Timestamp created_at) : created_at_(created_at) {}

  std::vector<uint8_t> Serialize() {
    uint32_t high_bits = static_cast<uint32_t>(created_at_.ms() >> 32);
    uint32_t low_bits = static_cast<uint32_t>(created_at_.ms());

    std::vector<uint8_t> data(kBufferSize);
    BoundedByteWriter<kBufferSize> writer(data);
    writer.Store32<0>(high_bits);
    writer.Store32<4>(low_bits);
    return data;
  }

  static std::optional<HeartbeatInfo> Deserialize(
      std::span<const uint8_t> data) {
    if (data.size() != kBufferSize) {
      RTC_LOG(LS_WARNING) << "Invalid heartbeat info: " << data.size()
                          << " bytes";
      return std::nullopt;
    }

    BoundedByteReader<kBufferSize> reader(data);
    uint32_t high_bits = reader.Load32<0>();
    uint32_t low_bits = reader.Load32<4>();

    uint64_t created_at = static_cast<uint64_t>(high_bits) << 32 | low_bits;
    return HeartbeatInfo(Timestamp::Millis(created_at));
  }

  Timestamp created_at() const { return created_at_; }

 private:
  const Timestamp created_at_;
};

HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix,
                                   const DcSctpOptions& options,
                                   Context* context,
                                   TimerManager* timer_manager)
    : log_prefix_(log_prefix),
      ctx_(context),
      timer_manager_(timer_manager),
      interval_duration_(options.heartbeat_interval.ToTimeDelta()),
      interval_duration_should_include_rtt_(
          options.heartbeat_interval_include_rtt),
      interval_timer_(timer_manager_->CreateTimer(
          "heartbeat-interval",
          absl::bind_front(&HeartbeatHandler::OnIntervalTimerExpiry, this),
          TimerOptions(interval_duration_, TimerBackoffAlgorithm::kFixed))),
      timeout_timer_(timer_manager_->CreateTimer(
          "heartbeat-timeout",
          absl::bind_front(&HeartbeatHandler::OnTimeoutTimerExpiry, this),
          TimerOptions(options.rto_initial.ToTimeDelta(),
                       TimerBackoffAlgorithm::kExponential,
                       /*max_restarts=*/0))) {
  // The interval timer must always be running as long as the association is up.
  RestartTimer();
}

void HeartbeatHandler::RestartTimer() {
  if (interval_duration_.IsZero()) {
    // Heartbeating has been disabled.
    return;
  }

  if (interval_duration_should_include_rtt_) {
    // The RTT should be used, but it's not easy accessible. The RTO will
    // suffice.
    interval_timer_->set_duration(interval_duration_ + ctx_->current_rto());
  } else {
    interval_timer_->set_duration(interval_duration_);
  }

  interval_timer_->Start();
}

void HeartbeatHandler::HandleHeartbeatRequest(HeartbeatRequestChunk chunk) {
  // https://tools.ietf.org/html/rfc4960#section-8.3
  // "The receiver of the HEARTBEAT should immediately respond with a
  // HEARTBEAT ACK that contains the Heartbeat Information TLV, together with
  // any other received TLVs, copied unchanged from the received HEARTBEAT
  // chunk."
  ctx_->Send(ctx_->PacketBuilder().Add(
      HeartbeatAckChunk(std::move(chunk).extract_parameters())));
}

void HeartbeatHandler::HandleHeartbeatAck(HeartbeatAckChunk chunk) {
  timeout_timer_->Stop();
  std::optional<HeartbeatInfoParameter> info_param = chunk.info();
  if (!info_param.has_value()) {
    ctx_->callbacks().OnError(
        ErrorKind::kParseFailed,
        "Failed to parse HEARTBEAT-ACK; No Heartbeat Info parameter");
    return;
  }
  std::optional<HeartbeatInfo> info =
      HeartbeatInfo::Deserialize(info_param->info());
  if (!info.has_value()) {
    ctx_->callbacks().OnError(ErrorKind::kParseFailed,
                              "Failed to parse HEARTBEAT-ACK; Failed to "
                              "deserialized Heartbeat info parameter");
    return;
  }

  Timestamp now = ctx_->callbacks().Now();
  if (info->created_at() > Timestamp::Zero() && info->created_at() <= now) {
    ctx_->ObserveRTT(now - info->created_at());
  }

  // https://tools.ietf.org/html/rfc4960#section-8.1
  // "The counter shall be reset each time ... a HEARTBEAT ACK is received from
  // the peer endpoint."
  ctx_->ClearTxErrorCounter();
}

TimeDelta HeartbeatHandler::OnIntervalTimerExpiry() {
  if (ctx_->is_connection_established()) {
    HeartbeatInfo info(ctx_->callbacks().Now());
    timeout_timer_->set_duration(ctx_->current_rto());
    timeout_timer_->Start();
    RTC_DLOG(LS_INFO) << log_prefix_ << "Sending HEARTBEAT with timeout "
                      << webrtc::ToString(timeout_timer_->duration());

    Parameters parameters = Parameters::Builder()
                                .Add(HeartbeatInfoParameter(info.Serialize()))
                                .Build();

    ctx_->Send(ctx_->PacketBuilder().Add(
        HeartbeatRequestChunk(std::move(parameters))));
  } else {
    RTC_DLOG(LS_VERBOSE)
        << log_prefix_
        << "Will not send HEARTBEAT when connection not established";
  }
  return TimeDelta::Zero();
}

TimeDelta HeartbeatHandler::OnTimeoutTimerExpiry() {
  // Note that the timeout timer is not restarted. It will be started again when
  // the interval timer expires.
  RTC_DCHECK(!timeout_timer_->is_running());
  ctx_->IncrementTxErrorCounter("HEARTBEAT timeout");
  return TimeDelta::Zero();
}
}  // namespace dcsctp
