/*
 *  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 <stddef.h>

#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/bind_front.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/units/time_delta.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/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(
      rtc::ArrayView<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
