/*
 *  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.
 */
#ifndef NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_
#define NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_

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

#include "absl/strings/string_view.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "net/dcsctp/public/dcsctp_message.h"
#include "net/dcsctp/public/dcsctp_socket.h"
#include "net/dcsctp/public/timeout.h"
#include "net/dcsctp/public/types.h"
#include "net/dcsctp/timer/fake_timeout.h"
#include "rtc_base/logging.h"
#include "rtc_base/random.h"
#include "test/gmock.h"

namespace dcsctp {

namespace internal {
// It can be argued if a mocked random number generator should be deterministic
// or if it should be have as a "real" random number generator. In this
// implementation, each instantiation of `MockDcSctpSocketCallbacks` will have
// their `GetRandomInt` return different sequences, but each instantiation will
// always generate the same sequence of random numbers. This to make it easier
// to compare logs from tests, but still to let e.g. two different sockets (used
// in the same test) get different random numbers, so that they don't start e.g.
// on the same sequence number. While that isn't an issue in the protocol, it
// just makes debugging harder as the two sockets would look exactly the same.
//
// In a real implementation of `DcSctpSocketCallbacks` the random number
// generator backing `GetRandomInt` should be seeded externally and correctly.
inline int GetUniqueSeed() {
  static int seed = 0;
  return ++seed;
}
}  // namespace internal

class MockDcSctpSocketCallbacks : public DcSctpSocketCallbacks {
 public:
  explicit MockDcSctpSocketCallbacks(absl::string_view name = "")
      : log_prefix_(name.empty() ? "" : std::string(name) + ": "),
        random_(internal::GetUniqueSeed()),
        timeout_manager_([this]() { return now_; }) {
    ON_CALL(*this, SendPacketWithStatus)
        .WillByDefault([this](std::span<const uint8_t> data) {
          sent_packets_.emplace_back(
              std::vector<uint8_t>(data.begin(), data.end()));
          return SendPacketStatus::kSuccess;
        });
    ON_CALL(*this, OnMessageReceived)
        .WillByDefault([this](DcSctpMessage message) {
          received_messages_.emplace_back(std::move(message));
        });

    ON_CALL(*this, OnError)
        .WillByDefault([this](ErrorKind error, absl::string_view message) {
          RTC_LOG(LS_WARNING)
              << log_prefix_ << "Socket error: " << ToString(error) << "; "
              << message;
        });
    ON_CALL(*this, OnAborted)
        .WillByDefault([this](ErrorKind error, absl::string_view message) {
          RTC_LOG(LS_WARNING)
              << log_prefix_ << "Socket abort: " << ToString(error) << "; "
              << message;
        });
    ON_CALL(*this, Now).WillByDefault([this]() { return now_; });
  }

  MOCK_METHOD(SendPacketStatus,
              SendPacketWithStatus,
              (std::span<const uint8_t> data),
              (override));

  std::unique_ptr<Timeout> CreateTimeout(
      webrtc::TaskQueueBase::DelayPrecision /* precision */) override {
    // The fake timeout manager does not implement |precision|.
    return timeout_manager_.CreateTimeout();
  }

  MOCK_METHOD(webrtc::Timestamp, Now, (), (override));
  uint32_t GetRandomInt(uint32_t low, uint32_t high) override {
    return random_.Rand(low, high);
  }

  MOCK_METHOD(void, OnMessageReceived, (DcSctpMessage message), (override));
  MOCK_METHOD(void, OnMessageReady, (), (override));
  MOCK_METHOD(void,
              OnError,
              (ErrorKind error, absl::string_view message),
              (override));
  MOCK_METHOD(void,
              OnAborted,
              (ErrorKind error, absl::string_view message),
              (override));
  MOCK_METHOD(void, OnConnected, (), (override));
  MOCK_METHOD(void, OnClosed, (), (override));
  MOCK_METHOD(void, OnConnectionRestarted, (), (override));
  MOCK_METHOD(void,
              OnStreamsResetFailed,
              (std::span<const StreamID> outgoing_streams,
               absl::string_view reason),
              (override));
  MOCK_METHOD(void,
              OnStreamsResetPerformed,
              (std::span<const StreamID> outgoing_streams),
              (override));
  MOCK_METHOD(void,
              OnIncomingStreamsReset,
              (std::span<const StreamID> incoming_streams),
              (override));
  MOCK_METHOD(void, OnBufferedAmountLow, (StreamID stream_id), (override));
  MOCK_METHOD(void, OnTotalBufferedAmountLow, (), (override));
  MOCK_METHOD(void,
              OnLifecycleMessageExpired,
              (LifecycleId lifecycle_id, bool maybe_delivered),
              (override));
  MOCK_METHOD(void,
              OnLifecycleMessageFullySent,
              (LifecycleId lifecycle_id),
              (override));
  MOCK_METHOD(void,
              OnLifecycleMessageDelivered,
              (LifecycleId lifecycle_id),
              (override));
  MOCK_METHOD(void, OnLifecycleEnd, (LifecycleId lifecycle_id), (override));

  bool HasPacket() const { return !sent_packets_.empty(); }

  std::vector<uint8_t> ConsumeSentPacket() {
    if (sent_packets_.empty()) {
      return {};
    }
    std::vector<uint8_t> ret = std::move(sent_packets_.front());
    sent_packets_.pop_front();
    return ret;
  }
  std::optional<DcSctpMessage> ConsumeReceivedMessage() {
    if (received_messages_.empty()) {
      return std::nullopt;
    }
    DcSctpMessage ret = std::move(received_messages_.front());
    received_messages_.pop_front();
    return ret;
  }

  void AdvanceTime(webrtc::TimeDelta duration) { now_ = now_ + duration; }
  void SetTime(webrtc::Timestamp now) { now_ = now; }

  std::optional<TimeoutID> GetNextExpiredTimeout() {
    return timeout_manager_.GetNextExpiredTimeout();
  }

  webrtc::TimeDelta GetTimeToNextTimeout() const {
    return timeout_manager_.GetTimeToNextTimeout();
  }

 private:
  const std::string log_prefix_;
  webrtc::Timestamp now_ = webrtc::Timestamp::Zero();
  webrtc::Random random_;
  FakeTimeoutManager timeout_manager_;
  std::deque<std::vector<uint8_t>> sent_packets_;
  std::deque<DcSctpMessage> received_messages_;
};
}  // namespace dcsctp

#endif  // NET_DCSCTP_SOCKET_MOCK_DCSCTP_SOCKET_CALLBACKS_H_
