/** @file
 *
 *  A brief file description
 *
 *  @section license License
 *
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#pragma once

#include <string>
#include <yaml-cpp/yaml.h>

#include "QUICTypes.h"
#include "QLogEvent.h"
#include "QLogFrame.h"

namespace QLog
{
class QLogEvent
{
public:
  virtual ~QLogEvent() {}

  virtual std::string category() const = 0;
  virtual std::string event() const    = 0;
  virtual void encode(YAML::Node &)    = 0;

  virtual ink_hrtime
  get_time() const
  {
    return this->_time;
  };

protected:
  ink_hrtime _time = Thread::get_hrtime();
};

using QLogEventUPtr = std::unique_ptr<QLogEvent>;

#define SET(field, type) \
  void set_##field(type v) { this->_node[#field] = v; }

// enum class PacketType : uint8_t { initial, handshake, zerortt, onertt, retry, version_negotiation, unknown };
using PacketType = std::string;

struct PacketHeader {
  std::string packet_number;
  uint64_t packet_size;
  uint64_t payload_length;

  // only if present in the header
  // if correctly using NEW_CONNECTION_ID events,
  // dcid can be skipped for 1RTT packets
  std::string version;
  std::string scil;
  std::string dcil;
  std::string scid;
  std::string dcid;

  // Note: short vs long header is implicit through PacketType
  void
  encode(YAML::Node &node) const
  {
    node["packet_number"]  = packet_number;
    node["packet_size"]    = packet_size;
    node["payload_length"] = payload_length;
    node["version"]        = version;
    node["scil"]           = scil;
    node["dcil"]           = dcil;
    node["scid"]           = scid;
    node["dcid"]           = dcid;
  }
};

#define SET_FUNC(cla, field, type) \
public:                            \
  cla &set_##field(const type &v)  \
  {                                \
    this->_##field = v;            \
    return *this;                  \
  }                                \
                                   \
private:                           \
  type _##field;

#define APPEND_FUNC(cla, field, type) \
public:                               \
  cla &append_##field(type v)         \
  {                                   \
    this->_##field.push_back(v);      \
    return *this;                     \
  }                                   \
                                      \
private:                              \
  std::vector<type> _##field;

#define APPEND_FRAME_FUNC(cla)             \
public:                                    \
  cla &append_frames(QLogFrameUPtr v)      \
  {                                        \
    this->_frames.push_back(std::move(v)); \
    return *this;                          \
  }                                        \
                                           \
private:                                   \
  std::vector<QLogFrameUPtr> _frames;

//
// connectivity
//
namespace Connectivity
{
  class ConnectivityEvent : public QLogEvent
  {
  public:
    std::string
    category() const override
    {
      return "connectivity";
    }
  };

  class ServerListening : public ConnectivityEvent
  {
  public:
    ServerListening(int port, bool v6 = false)
    {
      if (v6) {
        set_port_v6(port);
      } else {
        set_port_v4(port);
      }
    }

#define _SET(a, b) SET_FUNC(ServerListening, a, b)
#define _APPEND(a, b) APPEND_FUNC(ServerListening, a, b)
    _SET(port_v4, int)
    _SET(port_v6, int)
    _SET(ip_v4, std::string)
    _SET(ip_v6, std::string)
    _SET(stateless_reset_required, bool)
    _APPEND(quic_version, std::string)
    _APPEND(alpn_values, std::string)

#undef _SET
#undef _APPEND

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "server_listening";
    }
  };

  class ConnectionStarted : public ConnectivityEvent
  {
  public:
    ConnectionStarted(const std::string &version, const std::string &sip, const std::string &dip, int sport, int dport,
                      const std::string &protocol = "QUIC")
    {
      set_ip_version(version);
      set_protocol(protocol);
      set_src_ip(sip);
      set_dst_ip(dip);
      set_src_port(sport);
      set_dst_port(dport);
    }

#define _SET(a, b) SET_FUNC(ConnectionStarted, a, b)
#define _APPEND(a, b) APPEND_FUNC(ConnectionStarted, a, b)
    _SET(quic_version, std::string);
    _SET(src_cid, std::string);
    _SET(dst_cid, std::string);
    _SET(protocol, std::string);
    _SET(ip_version, std::string)
    _SET(src_ip, std::string)
    _SET(dst_ip, std::string)
    _SET(src_port, int)
    _SET(dst_port, int)
    _APPEND(alpn_values, std::string)

#undef _SET
#undef _APPEND

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "connection_started";
    }
  };

  class ConnectionIdUpdated : public ConnectivityEvent
  {
  public:
    ConnectionIdUpdated(const std::string &old, const std::string &n, bool peer = false)
    {
      if (peer) {
        set_dst_old(old);
        set_dst_new(n);
      } else {
        set_src_old(old);
        set_src_new(n);
      }
    }

#define _SET(a, b) SET_FUNC(ConnectionIdUpdated, a, b)
#define _APPEND(a, b) APPEND_FUNC(ConnectionIdUpdated, a, b)

    _SET(src_old, std::string);
    _SET(src_new, std::string);
    _SET(dst_old, std::string);
    _SET(dst_new, std::string);

#undef _SET
#undef _APPEND

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "connection_id_updated";
    }
  };

  class SpinBitUpdated : public ConnectivityEvent
  {
  public:
    SpinBitUpdated(bool state) { set_state(state); }

#define _SET(a, b) SET_FUNC(SpinBitUpdated, a, b)
    _SET(state, bool);
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "spin_bit_updated";
    }
  };

  class ConnectionStateUpdated : public ConnectivityEvent
  {
  public:
    enum class ConnectionState : uint8_t {
      attempted, // client initial sent
      reset,     // stateless reset sent
      handshake, // handshake in progress
      active,    // handshake successful, data exchange
      keepalive, // no data for a longer period
      draining,  // CONNECTION_CLOSE sent
      closed     // connection actually fully closed, memory freed
    };

    enum class Triggered : uint8_t {
      unknown,
      error,      // when closing because of an unexpected event
      clean,      // when closing normally
      application // e.g., HTTP/3's GOAWAY frame
    };

    ConnectionStateUpdated(ConnectionState n, Triggered tr = Triggered::unknown)
    {
      set_new(n);
      set_trigger(tr);
    }

#define _SET(a, b) SET_FUNC(ConnectionStateUpdated, a, b)
    _SET(new, ConnectionState);
    _SET(old, ConnectionState);
    _SET(trigger, Triggered)

#undef _SET

    void encode(YAML::Node &) override;

    static const char *
    trigger_name(Triggered trigger)
    {
      switch (trigger) {
      case Triggered::error:
        return "error";
      case Triggered::clean:
        return "clean";
      case Triggered::application:
        return "application";
      default:
        return nullptr;
      }
    }

    std::string
    event() const override
    {
      return "connection_state_updated";
    }
  };

} // namespace Connectivity

namespace Security
{
  class KeyEvent : public QLogEvent
  {
  public:
    enum class KeyType : uint8_t {
      server_initial_secret,
      client_initial_secret,

      server_handshake_secret,
      client_handshake_secret,

      server_0rtt_secret,
      client_0rtt_secret,

      server_1rtt_secret,
      client_1rtt_secret
    };

    enum class Triggered : uint8_t {
      unknown,
      remote_update,
      local_update,
      tls,
    };

    KeyEvent(KeyType ty, const std::string &n, int generation, Triggered triggered = Triggered::unknown)
    {
      set_key_type(ty);
      set_new(n);
      set_generation(generation);
      set_trigger(triggered);
    }

#define _SET(a, b) SET_FUNC(KeyEvent, a, b)
    _SET(key_type, KeyType);
    _SET(new, std::string)
    _SET(old, std::string);
    _SET(generation, int)
    _SET(trigger, Triggered)
#undef _SET

    void encode(YAML::Node &) override;

    const char *
    trigger_name(Triggered triggered)
    {
      switch (triggered) {
      case Triggered::remote_update:
        return "remote_update";
      case Triggered::local_update:
        return "local_update";
      case Triggered::tls:
        return "tls";
      default:
        return nullptr;
      }
    }

    std::string
    category() const override
    {
      return "security";
    }
  };

  class KeyUpdated : public KeyEvent
  {
  public:
    KeyUpdated(KeyType ty, const std::string &n, int generation, Triggered triggered = KeyEvent::Triggered::unknown)
      : KeyEvent(ty, n, generation, triggered)
    {
    }

    std::string
    event() const override
    {
      return "key_updated";
    }
  };

  class KeyRetired : public KeyEvent
  {
  public:
    KeyRetired(KeyType ty, const std::string &n, int generation, Triggered triggered = KeyEvent::Triggered::unknown)
      : KeyEvent(ty, n, generation, triggered)
    {
    }

    std::string
    event() const override
    {
      return "key_retired";
    }
  };

} // namespace Security

//
// transport event
//
namespace Transport
{
  class TransportEvent : public QLogEvent
  {
  public:
    std::string
    category() const override
    {
      return "transport";
    }
  };

  class ParametersSet : public TransportEvent
  {
  public:
    struct PreferredAddress {
      std::string ip;
      int port;
      std::string connection_id;
      std::string stateless_reset_token;
      bool ipv4 = true;
    };

    ParametersSet(bool owner) : _owner(owner) {}

    std::string
    event() const override
    {
      return "parameters_set";
    }

#define _SET(a, b) SET_FUNC(ParametersSet, a, b)
    _SET(resumption_allowed, bool); // early data extension was enabled on the TLS layer
    _SET(early_data_enabled, bool); // early data extension was enabled on the TLS layer
    _SET(alpn, std::string);
    _SET(version, std::string);                // hex (e.g. 0x);
    _SET(tls_cipher, std::string);             // (e.g. AES_128_GCM_SHA256);
    _SET(original_connection_id, std::string); // hex
    _SET(stateless_reset_token, std::string);  // hex
    _SET(disable_active_migration, bool);
    _SET(idle_timeout, int);
    _SET(max_packet_size, int);
    _SET(ack_delay_exponent, int);
    _SET(max_ack_delay, int);
    _SET(active_connection_id_limit, int);
    _SET(initial_max_data, std::string);
    _SET(initial_max_stream_data_bidi_local, std::string);
    _SET(initial_max_stream_data_bidi_remote, std::string);
    _SET(initial_max_stream_data_uni, std::string);
    _SET(initial_max_streams_bidi, std::string);
    _SET(initial_max_streams_uni, std::string);
    _SET(max_idle_timeout, int64_t)
    _SET(max_udp_payload_size, size_t)
    _SET(preferred_address, PreferredAddress)
#undef _SET

    void encode(YAML::Node &) override;

  private:
    bool _owner = false;
  };

  class PacketEvent : public TransportEvent
  {
  public:
    enum class Triggered : uint8_t {
      unknown,
      keys_available,       // if packet was buffered because it couldn't be decrypted before
      retransmit_reordered, // draft-23 5.1.1
      retransmit_timeout,   // draft-23 5.1.2
      pto_probe,            // draft-23 5.3.1
      retransmit_crypto,    // draft-19 6.2
      cc_bandwidth_probe,   // needed for some CCs to figure out bandwidth allocations when there are no normal sends
    };

    PacketEvent(const PacketType &type, PacketHeader h, Triggered tr = Triggered::unknown)
    {
      set_packet_type(type).set_header(h).set_trigger(tr);
    }

#define _SET(a, b) SET_FUNC(PacketEvent, a, b)
#define _APPEND(a, b) APPEND_FUNC(PacketEvent, a, b)
    _SET(packet_type, PacketType)
    _SET(header, PacketHeader)
    _SET(is_coalesced, bool);
    _SET(raw_encrypted, std::string);
    _SET(raw_decrypted, std::string);
    _SET(stateless_reset_token, std::string);
    _SET(trigger, Triggered);
    _APPEND(supported_version, std::string);

#undef _SET
#undef _APPEND
    APPEND_FRAME_FUNC(PacketEvent)

    void encode(YAML::Node &) override;

    static const char *
    trigger_name(Triggered triggered)
    {
      switch (triggered) {
      case Triggered::retransmit_reordered:
        return "retransmit_reordered";
      case Triggered::retransmit_timeout:
        return "retransmit_timeout";
      case Triggered::pto_probe:
        return "pto_probe";
      case Triggered::retransmit_crypto:
        return "retransmit_crypto";
      case Triggered::cc_bandwidth_probe:
        return "cc_bandwidth_probe";
        break;
      case Triggered::keys_available:
        return "keys_available";
      default:
        return nullptr;
      }
    }
  };

  class PacketSent : public PacketEvent
  {
  public:
    PacketSent(const PacketType &type, const PacketHeader &h, Triggered tr = Triggered::unknown) : PacketEvent(type, h, tr) {}
    std::string
    event() const override
    {
      return "packet_sent";
    }
  };

  class PacketReceived : public PacketEvent
  {
  public:
    PacketReceived(const PacketType &type, const PacketHeader &h, Triggered tr = Triggered::unknown) : PacketEvent(type, h, tr) {}
    std::string
    event() const override
    {
      return "packet_received";
    }
  };

  class PacketDropped : public TransportEvent
  {
  public:
    enum class Triggered : uint8_t {
      unknown,
      key_unavailable,
      unknown_connection_id,
      header_decrypt_error,
      payload_decrypt_error,
      protocol_violation,
      dos_prevention,
      unsupported_version,
      unexpected_packet,
      unexpected_source_connection_id,
      unexpected_version,
    };

    PacketDropped(Triggered tr = Triggered::unknown) { set_trigger(tr); }

#define _SET(a, b) SET_FUNC(PacketDropped, a, b)
    _SET(packet_size, int);
    _SET(raw, std::string);
    _SET(trigger, Triggered);
    _SET(packet_type, PacketType)
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "packet_dropped";
    }

    static const char *
    trigger_name(Triggered tr)
    {
      switch (tr) {
      case Triggered::key_unavailable:
        return "key_unavailable";
      case Triggered::unknown_connection_id:
        return "unknown_connection_id";
      case Triggered::header_decrypt_error:
        return "header_decrypt_error";
      case Triggered::payload_decrypt_error:
        return "payload_decrypt_error";
      case Triggered::protocol_violation:
        return "protocol_violation";
      case Triggered::dos_prevention:
        return "dos_prevention";
      case Triggered::unsupported_version:
        return "unsupported_version";
      case Triggered::unexpected_packet:
        return "unexpected_packet";
      case Triggered::unexpected_source_connection_id:
        return "unexpected_source_connection_id";
      case Triggered::unexpected_version:
        return "unexpected_version";
      default:
        return nullptr;
      }
    }
  };

  class PacketBuffered : public TransportEvent
  {
  public:
    enum class Triggered : uint8_t {
      unknown,
      backpressure,
      keys_unavailable,
    };

    PacketBuffered(Triggered tr = Triggered::unknown) { set_trigger(tr); }

#define _SET(a, b) SET_FUNC(PacketBuffered, a, b)
    _SET(trigger, Triggered);
    _SET(packet_type, PacketType)
    _SET(packet_number, std::string)
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "packet_buffered";
    }

    static const char *
    trigger_name(Triggered tr)
    {
      switch (tr) {
      case Triggered::backpressure:
        return "backpressure";
      case Triggered::keys_unavailable:
        return "keys_unavailable";
      default:
        return nullptr;
      }
    }
  };

  class DatagramsEvent : public TransportEvent
  {
  public:
#define _SET(a, b) SET_FUNC(DatagramsEvent, a, b)
    _SET(count, int);
    _SET(byte_length, int);
#undef _SET
    void encode(YAML::Node &) override;
  };

  class DatagramsSent : public DatagramsEvent
  {
  public:
    std::string
    event() const override
    {
      return "datagrams_sent";
    }
  };
  class DatagramReceived : public DatagramsEvent
  {
  public:
    std::string
    event() const override
    {
      return "datagrams_received";
    }
  };

  class DatagramsDropped : public TransportEvent
  {
  public:
#define _SET(a, b) SET_FUNC(DatagramsDropped, a, b)
    _SET(byte_length, int);
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "datagrams_dropped";
    }
  };

  class StreamStateUpdated : public TransportEvent
  {
    enum class StreamState {
      // bidirectional stream states, draft-23 3.4.
      idle,
      open,
      half_closed_local,
      half_closed_remote,
      closed,

      // sending-side stream states, draft-23 3.1.
      ready,
      send,
      data_sent,
      reset_sent,
      reset_received,

      // receive-side stream states, draft-23 3.2.
      receive,
      size_known,
      data_read,
      reset_read,

      // both-side states
      data_received,

      // qlog-defined
      destroyed // memory actually freed
    };

    StreamStateUpdated(std::string stream_id, StreamState n) { set_new(n).set_stream_id(stream_id); }

    void encode(YAML::Node &) override;

#define _SET(a, b) SET_FUNC(StreamStateUpdated, a, b)
    _SET(new, StreamState);
    _SET(old, StreamState);
    _SET(stream_id, std::string);
    _SET(bidi, bool);
#undef _SET

    std::string
    event() const override
    {
      return "stream_state_updated";
    }
  };

  class FrameProcessed : public TransportEvent
  {
  public:
    APPEND_FRAME_FUNC(FrameProcessed)

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "frame_processed";
    }
  };

} // namespace Transport

namespace Recovery
{
  class RecoveryEvent : public QLogEvent
  {
  public:
    std::string
    category() const override
    {
      return "recovery";
    }
  };

  class ParametersSet : public RecoveryEvent
  {
  public:
#define _SET(a, b) SET_FUNC(ParametersSet, a, b)
    _SET(reordering_threshold, int);
    _SET(time_threshold, int);
    _SET(timer_granularity, int);
    _SET(initial_rtt, int);
    _SET(max_datagram_size, int);
    _SET(initial_congestion_window, int);
    _SET(minimum_congestion_window, int);
    _SET(loss_reduction_factor, int);
    _SET(persistent_congestion_threshold, int);
#undef _SET
    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "parameters_set";
    }
  };

  class MetricsUpdated : public RecoveryEvent
  {
  public:
#define _SET(a, b) SET_FUNC(MetricsUpdated, a, b)
    _SET(min_rtt, int);
    _SET(smoothed_rtt, int);
    _SET(latest_rtt, int);
    _SET(rtt_variance, int);
    _SET(max_ack_delay, int);
    _SET(pto_count, int);
    _SET(congestion_window, int);
    _SET(bytes_in_flight, int);
    _SET(ssthresh, int);
    _SET(packets_in_flight, int);
    _SET(in_recovery, int);
    _SET(pacing_rate, int);
#undef _SET
    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "metrics_updated";
    }
  };

  class CongestionStateUpdated : public RecoveryEvent
  {
  public:
    enum class State : uint8_t {
      slow_start,
      congestion_avoidance,
      application_limited,
      recovery,
    };

    enum class Triggered : uint8_t {
      unknown,
      persistent_congestion,
      ECN,
    };

    CongestionStateUpdated(State n, Triggered tr = Triggered::unknown) { set_trigger(tr).set_new(n); }

#define _SET(a, b) SET_FUNC(CongestionStateUpdated, a, b)
    _SET(trigger, Triggered)
    _SET(new, State)
    _SET(old, State)
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "congestion_state_updated";
    }

    static const char *
    trigger_name(Triggered tr)
    {
      switch (tr) {
      case Triggered::persistent_congestion:
        return "persistent_congestion";
      case Triggered::ECN:
        return "ECN";
      default:
        return nullptr;
      }
    }

    static const char *
    state_to_string(State s)
    {
      switch (s) {
      case State::slow_start:
        return "slow_start";
      case State::congestion_avoidance:
        return "congestion_avoidance";
      case State::application_limited:
        return "application_limited";
      case State::recovery:
        return "recovery";
      default:
        break;
      }

      return nullptr;
    }
  };

  class LossTimerUpdated : public RecoveryEvent
  {
  public:
    enum class EventType : uint8_t {
      set,
      expired,
      cancelled,
    };

    void
    set_timer_type(bool ack)
    {
      this->_timer_type_ack = ack;
    }

    void encode(YAML::Node &) override;

#define _SET(a, b) SET_FUNC(LossTimerUpdated, a, b)
    _SET(event_type, EventType)
    _SET(packet_number_space, int);
    _SET(delta, int);
#undef _SET

    std::string
    event() const override
    {
      return "loss_timer_updated";
    }

    static const char *
    event_type_name(EventType et)
    {
      switch (et) {
      case EventType::set:
        return "set";
      case EventType::expired:
        return "expired";
      case EventType::cancelled:
        return "cancelled";
      default:
        break;
      }
      return nullptr;
    }

  private:
    bool _timer_type_ack = false;
  };

  class PacketLost : public RecoveryEvent
  {
  public:
    enum class Triggered : uint8_t {
      unknown,
      reordering_threshold,
      time_threshold,
      pto_expired,
    };

    PacketLost(PacketType pt, uint64_t pn, Triggered tr = Triggered::unknown)
    {
      set_trigger(tr).set_packet_type(pt).set_packet_number(pn);
    }

#define _SET(a, b) SET_FUNC(PacketLost, a, b)
    _SET(header, PacketHeader)
    _SET(packet_number, uint64_t);
    _SET(packet_type, PacketType);
    _SET(trigger, Triggered)
    APPEND_FRAME_FUNC(PacketLost)
#undef _SET

    void encode(YAML::Node &) override;

    std::string
    event() const override
    {
      return "packet_lost";
    }

    static const char *
    trigger_name(Triggered tr)
    {
      switch (tr) {
      case Triggered::pto_expired:
        return "pto_expired";
      case Triggered::reordering_threshold:
        return "reordering_threshold";
      case Triggered::time_threshold:
        return "time_threshold";
      default:
        return nullptr;
      }
    }
  };

  class MarkedForRetransmit : public RecoveryEvent
  {
  public:
    APPEND_FRAME_FUNC(MarkedForRetransmit)
    void encode(YAML::Node &) override;
    std::string
    event() const override
    {
      return "marked_for_retransmit";
    }
  };

} // namespace Recovery

} // namespace QLog
