// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_CONFIGURATION_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_CONFIGURATION_H_

#include <list>
#include <optional>

#include "src/connectivity/bluetooth/core/bt-host/common/byte_buffer.h"
#include "src/connectivity/bluetooth/core/bt-host/l2cap/l2cap_defs.h"

namespace bt::l2cap::internal {

// The ChannelConfiguration class is used for decoding and encoding channel configuration options
// (Core spec v5.1, Vol 3, Part A, Section 5) that are in the payloads of Configuration Requests
// (Section 4.4) and Configuration Responses (Section 4.5). To decode a configuration option payload
// in a configuration request/response signaling channel packet, instantiate a new
// ChannelConfiguration and read options into it via ReadOptions() (which may fail to decode invalid
// option payloads). Unknown options (ones we don't support) that are not hints (types 0x80-0xFF)
// are available via unknown_options(). Unknown options should always be handled by rejecting the
// packet containing them (Section 5).
//
// Decoding a configuration option payload example:
//   ChannelConfiguration config;
//   if (!config.ReadOptions(payload_buffer)) {
//     // Handle decoding failure
//   }
//   if (config.unknown_options.size() != 0) {
//     // Reject packet
//   }
//   if (config.mtu_option()) {
//     // Handle mtu option
//   }
//
// Subsequent configuration payload buffers and objects can be merged into an existing configuration
// with additional calls to ReadOptions() or Merge(), which will overwrite current options with the
// new ones.
//
// A channel configuration can be iterated through and encoded with ChannelConfiguration::Options(),
// which returns a vector of non-null options. All options can then be encoded into a
// DynamicByteBuffer with *.Encode().
//
// Encoding channel configuration options example:
//   ChannelConfiguration config;
//   config.set_mtu_option(MtuOption(mtu));
//   ConfigurationOption options = config.Options();
//   DynamicByteBuffer encoded_mtu = options[0].Encode();
//   payload_byte_buffer.Write(encoded_mtu);
class ChannelConfiguration final {
 public:
  class ConfigurationOptionInterface {
   public:
    virtual ~ConfigurationOptionInterface() = default;

    virtual DynamicByteBuffer Encode() const = 0;
    virtual std::string ToString() const = 0;
    virtual OptionType type() const = 0;
    virtual size_t size() const = 0;
  };

  using ConfigurationOptionPtr = std::unique_ptr<ConfigurationOptionInterface>;
  using ConfigurationOptions = std::vector<ConfigurationOptionPtr>;

  // Maximum Transmission Unit option (Core Spec v5.1, Vol 3, Part A, Sec 5.1).
  // Specifies the max SDU size the sender is capable of accepting on a channel.
  class MtuOption final : public ConfigurationOptionInterface {
   public:
    static constexpr OptionType kType = OptionType::kMTU;
    static constexpr uint8_t kPayloadLength = sizeof(MtuOptionPayload);
    static constexpr size_t kEncodedSize = sizeof(ConfigurationOption) + kPayloadLength;

    explicit MtuOption(uint16_t mtu) : mtu_(mtu) {}

    // |data_buf| must contain encoded Mtu option data. The option will be initialized with the
    // decoded fields.
    explicit MtuOption(const ByteBuffer& data_buf);

    uint16_t mtu() const { return mtu_; }

    // ConfigurationOptionInterface overrides

    DynamicByteBuffer Encode() const override;

    std::string ToString() const override;

    OptionType type() const override { return kType; }

    size_t size() const override { return kEncodedSize; }

   private:
    uint16_t mtu_;
  };

  // Retransmission and Flow Control option (Core Spec v5.1, Vol 3, Part A, Sec 5.4).
  // Specifies channel transmission mode and the values of related parameters.
  class RetransmissionAndFlowControlOption final : public ConfigurationOptionInterface {
   public:
    static constexpr OptionType kType = OptionType::kRetransmissionAndFlowControl;
    static constexpr uint8_t kPayloadLength = sizeof(RetransmissionAndFlowControlOptionPayload);
    static constexpr size_t kEncodedSize = sizeof(ConfigurationOption) + kPayloadLength;

    static RetransmissionAndFlowControlOption MakeBasicMode();

    static RetransmissionAndFlowControlOption MakeEnhancedRetransmissionMode(
        uint8_t tx_window_size, uint8_t max_transmit, uint16_t rtx_timeout,
        uint16_t monitor_timeout, uint16_t mps);

    // |data_buf| must contain encoded Retransmission And Flow Control option data. The option will
    // be initialized with the decoded fields.
    explicit RetransmissionAndFlowControlOption(const ByteBuffer& data_buf);

    ChannelMode mode() const { return mode_; }

    // TxWindow: receiver capability in request and transmit capability in response (ERTM)
    uint8_t tx_window_size() const { return tx_window_size_; }

    void set_tx_window_size(uint8_t tx_window_size) { tx_window_size_ = tx_window_size; }

    // MaxTransmit: retransmissions allowed before disconnecting (ERTM: 0 means infinite) in request
    // and ignored in response
    uint8_t max_transmit() const { return max_transmit_; }

    void set_max_transmit(uint8_t max_transmit) { max_transmit_ = max_transmit; }

    // Retransmission time-out: 0 in request and error detection timeout in response (ERTM)
    uint16_t rtx_timeout() const { return rtx_timeout_; }

    void set_rtx_timeout(uint16_t rtx_timeout) { rtx_timeout_ = rtx_timeout; }

    // Monitor time-out: 0 in request and link loss detection timeout in response (ERTM)
    uint16_t monitor_timeout() const { return monitor_timeout_; }

    void set_monitor_timeout(uint16_t monitor_timeout) { monitor_timeout_ = monitor_timeout; }

    // Maximum PDU size
    uint16_t mps() const { return mps_; }

    void set_mps(uint16_t mps) { mps_ = mps; }

    // ConfigurationOptionInterface overrides

    DynamicByteBuffer Encode() const override;

    std::string ToString() const override;

    OptionType type() const override { return kType; }

    size_t size() const override { return kEncodedSize; }

   private:
    // If |mode| is kBasic, all other parameters are ignored.
    RetransmissionAndFlowControlOption(ChannelMode mode, uint8_t tx_window_size,
                                       uint8_t max_transmit, uint16_t rtx_timeout,
                                       uint16_t monitor_timeout, uint16_t mps);

    ChannelMode mode_;
    uint8_t tx_window_size_;
    uint8_t max_transmit_;
    uint16_t rtx_timeout_;
    uint16_t monitor_timeout_;
    uint16_t mps_;
  };

  // Flush Timeout option (Core Spec v5.1, Vol 3, Part A, Sec 5.2).
  // Specifies flush timeout that sender of this option is going to use.
  class FlushTimeoutOption final : public ConfigurationOptionInterface {
   public:
    static constexpr OptionType kType = OptionType::kFlushTimeout;
    static constexpr uint8_t kPayloadLength = sizeof(FlushTimeoutOptionPayload);
    static constexpr size_t kEncodedSize = sizeof(ConfigurationOption) + kPayloadLength;

    explicit FlushTimeoutOption(uint16_t flush_timeout) : flush_timeout_(flush_timeout) {}

    // |data_buf| must contain encoded Flush Timeout option data. The option will be initialized
    // with the encoded flush timeout field.
    explicit FlushTimeoutOption(const ByteBuffer& data_buf);

    uint16_t flush_timeout() const { return flush_timeout_; }

    // ConfigurationOptionInterface overrides

    DynamicByteBuffer Encode() const override;

    std::string ToString() const override;

    OptionType type() const override { return kType; }

    size_t size() const override { return kEncodedSize; }

   private:
    uint16_t flush_timeout_;
  };

  // Unknown options that are not hints must be stored and sent in the Configuration Response.
  // (Core Spec v5.1, Vol 3, Sec 4.5)
  class UnknownOption final : public ConfigurationOptionInterface {
   public:
    UnknownOption(OptionType type, uint8_t length, const ByteBuffer& data);

    // Returns true if the unkown option is a hint and may be ignored/skipped. Returns false if
    // the unknown option may not be ignored (the request containing this option must be
    // refused).
    bool IsHint() const;

    const ByteBuffer& payload() const { return payload_; }

    // ConfigurationOptionInterface overrides

    DynamicByteBuffer Encode() const override;

    // Only includes the type, since options can't be decoded.
    std::string ToString() const override;

    OptionType type() const override { return type_; }

    size_t size() const override { return sizeof(ConfigurationOption) + payload_.size(); }

   private:
    OptionType type_;
    // Raw option payload buffer, since we can't parse it but we must create a response with it.
    DynamicByteBuffer payload_;
  };

  // Update this configuration based on other configuration's options. Used for accumulating
  // configuration options sent in a series of packets. Options that are already set in this
  // configuration will be overwritten if they are set in |other|. Unknown options will be appended
  // to the unknown options in this configuration.
  void Merge(ChannelConfiguration other);

  // Read encoded list of configuration options from |buffer| and update options accordingly.
  // Returns true if all options decoded successfully.
  [[nodiscard]] bool ReadOptions(const ByteBuffer& options_payload);

  // Convenience method that returns a vector containing only the options that have been set. Does
  // not include unknown options.
  ConfigurationOptions Options() const;

  // Returns a user-friendly string representation. This is intended for debug messages
  std::string ToString() const;

  void set_mtu_option(std::optional<MtuOption> option) { mtu_option_ = std::move(option); }

  void set_retransmission_flow_control_option(
      std::optional<RetransmissionAndFlowControlOption> option) {
    retransmission_flow_control_option_ = std::move(option);
  }

  void set_flush_timeout_option(std::optional<FlushTimeoutOption> option) {
    flush_timeout_option_ = std::move(option);
  }

  // Returns MtuOption only if it has been previously read or set.
  const std::optional<MtuOption>& mtu_option() const { return mtu_option_; }

  // Returns RetransmissionAndFlowControlOption only if it has been previously read or set.
  const std::optional<RetransmissionAndFlowControlOption>& retransmission_flow_control_option()
      const {
    return retransmission_flow_control_option_;
  }

  const std::optional<FlushTimeoutOption>& flush_timeout_option() const {
    return flush_timeout_option_;
  }

  // Returns unknown options previously decoded by |ReadOptions|. Used for responding to peer with
  // rejected options.
  const std::vector<UnknownOption>& unknown_options() const { return unknown_options_; }

 private:
  // Decoding callbacks
  void OnReadMtuOption(MtuOption option) { mtu_option_ = option; }
  void OnReadRetransmissionAndFlowControlOption(RetransmissionAndFlowControlOption option) {
    retransmission_flow_control_option_ = option;
  }
  void OnReadFlushTimeoutOption(FlushTimeoutOption option) { flush_timeout_option_ = option; }
  void OnReadUnknownOption(UnknownOption option);

  // Returns number of bytes read. A return value of 0 indicates failure to read option.
  size_t ReadNextOption(const ByteBuffer& options);

  std::optional<MtuOption> mtu_option_;
  std::optional<RetransmissionAndFlowControlOption> retransmission_flow_control_option_;
  std::optional<FlushTimeoutOption> flush_timeout_option_;
  std::vector<UnknownOption> unknown_options_;
};  // ChannelConfiguration

}  // namespace bt::l2cap::internal

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_CONFIGURATION_H_
