// 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.h"

namespace bt {
namespace l2cap {
namespace 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 internal
}  // namespace l2cap
}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_L2CAP_CHANNEL_CONFIGURATION_H_
