/*
 *  Copyright 2004 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 P2P_BASE_PSEUDOTCP_H_
#define P2P_BASE_PSEUDOTCP_H_

#include <list>

#include "rtc_base/basictypes.h"
#include "rtc_base/stream.h"

namespace cricket {

//////////////////////////////////////////////////////////////////////
// IPseudoTcpNotify
//////////////////////////////////////////////////////////////////////

class PseudoTcp;

class IPseudoTcpNotify {
 public:
  // Notification of tcp events
  virtual void OnTcpOpen(PseudoTcp* tcp) = 0;
  virtual void OnTcpReadable(PseudoTcp* tcp) = 0;
  virtual void OnTcpWriteable(PseudoTcp* tcp) = 0;
  virtual void OnTcpClosed(PseudoTcp* tcp, uint32_t error) = 0;

  // Write the packet onto the network
  enum WriteResult { WR_SUCCESS, WR_TOO_LARGE, WR_FAIL };
  virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
                                     const char* buffer, size_t len) = 0;

 protected:
  virtual ~IPseudoTcpNotify() {}
};

//////////////////////////////////////////////////////////////////////
// PseudoTcp
//////////////////////////////////////////////////////////////////////

class PseudoTcp {
 public:
  static uint32_t Now();

  PseudoTcp(IPseudoTcpNotify* notify, uint32_t conv);
  virtual ~PseudoTcp();

  int Connect();
  int Recv(char* buffer, size_t len);
  int Send(const char* buffer, size_t len);
  void Close(bool force);
  int GetError();

  enum TcpState {
    TCP_LISTEN, TCP_SYN_SENT, TCP_SYN_RECEIVED, TCP_ESTABLISHED, TCP_CLOSED
  };
  TcpState State() const { return m_state; }

  // Call this when the PMTU changes.
  void NotifyMTU(uint16_t mtu);

  // Call this based on timeout value returned from GetNextClock.
  // It's ok to call this too frequently.
  void NotifyClock(uint32_t now);

  // Call this whenever a packet arrives.
  // Returns true if the packet was processed successfully.
  bool NotifyPacket(const char * buffer, size_t len);

  // Call this to determine the next time NotifyClock should be called.
  // Returns false if the socket is ready to be destroyed.
  bool GetNextClock(uint32_t now, long& timeout);

  // Call these to get/set option values to tailor this PseudoTcp
  // instance's behaviour for the kind of data it will carry.
  // If an unrecognized option is set or got, an assertion will fire.
  //
  // Setting options for OPT_RCVBUF or OPT_SNDBUF after Connect() is called
  // will result in an assertion.
  enum Option {
    OPT_NODELAY,      // Whether to enable Nagle's algorithm (0 == off)
    OPT_ACKDELAY,     // The Delayed ACK timeout (0 == off).
    OPT_RCVBUF,       // Set the receive buffer size, in bytes.
    OPT_SNDBUF,       // Set the send buffer size, in bytes.
  };
  void GetOption(Option opt, int* value);
  void SetOption(Option opt, int value);

  // Returns current congestion window in bytes.
  uint32_t GetCongestionWindow() const;

  // Returns amount of data in bytes that has been sent, but haven't
  // been acknowledged.
  uint32_t GetBytesInFlight() const;

  // Returns number of bytes that were written in buffer and haven't
  // been sent.
  uint32_t GetBytesBufferedNotSent() const;

  // Returns current round-trip time estimate in milliseconds.
  uint32_t GetRoundTripTimeEstimateMs() const;

 protected:
  enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };

  struct Segment {
    uint32_t conv, seq, ack;
    uint8_t flags;
    uint16_t wnd;
    const char * data;
    uint32_t len;
    uint32_t tsval, tsecr;
  };

  struct SSegment {
    SSegment(uint32_t s, uint32_t l, bool c)
        : seq(s), len(l), /*tstamp(0),*/ xmit(0), bCtrl(c) {}
    uint32_t seq, len;
    // uint32_t tstamp;
    uint8_t xmit;
    bool bCtrl;
  };
  typedef std::list<SSegment> SList;

  struct RSegment {
    uint32_t seq, len;
  };

  uint32_t queue(const char* data, uint32_t len, bool bCtrl);

  // Creates a packet and submits it to the network. This method can either
  // send payload or just an ACK packet.
  //
  // |seq| is the sequence number of this packet.
  // |flags| is the flags for sending this packet.
  // |offset| is the offset to read from |m_sbuf|.
  // |len| is the number of bytes to read from |m_sbuf| as payload. If this
  // value is 0 then this is an ACK packet, otherwise this packet has payload.
  IPseudoTcpNotify::WriteResult packet(uint32_t seq,
                                       uint8_t flags,
                                       uint32_t offset,
                                       uint32_t len);
  bool parse(const uint8_t* buffer, uint32_t size);

  void attemptSend(SendFlags sflags = sfNone);

  void closedown(uint32_t err = 0);

  bool clock_check(uint32_t now, long& nTimeout);

  bool process(Segment& seg);
  bool transmit(const SList::iterator& seg, uint32_t now);

  void adjustMTU();

 protected:
  // This method is used in test only to query receive buffer state.
  bool isReceiveBufferFull() const;

  // This method is only used in tests, to disable window scaling
  // support for testing backward compatibility.
  void disableWindowScale();

 private:
  // Queue the connect message with TCP options.
  void queueConnectMessage();

  // Parse TCP options in the header.
  void parseOptions(const char* data, uint32_t len);

  // Apply a TCP option that has been read from the header.
  void applyOption(char kind, const char* data, uint32_t len);

  // Apply window scale option.
  void applyWindowScaleOption(uint8_t scale_factor);

  // Resize the send buffer with |new_size| in bytes.
  void resizeSendBuffer(uint32_t new_size);

  // Resize the receive buffer with |new_size| in bytes. This call adjusts
  // window scale factor |m_swnd_scale| accordingly.
  void resizeReceiveBuffer(uint32_t new_size);

  IPseudoTcpNotify* m_notify;
  enum Shutdown { SD_NONE, SD_GRACEFUL, SD_FORCEFUL } m_shutdown;
  int m_error;

  // TCB data
  TcpState m_state;
  uint32_t m_conv;
  bool m_bReadEnable, m_bWriteEnable, m_bOutgoing;
  uint32_t m_lasttraffic;

  // Incoming data
  typedef std::list<RSegment> RList;
  RList m_rlist;
  uint32_t m_rbuf_len, m_rcv_nxt, m_rcv_wnd, m_lastrecv;
  uint8_t m_rwnd_scale;  // Window scale factor.
  rtc::FifoBuffer m_rbuf;

  // Outgoing data
  SList m_slist;
  uint32_t m_sbuf_len, m_snd_nxt, m_snd_wnd, m_lastsend, m_snd_una;
  uint8_t m_swnd_scale;  // Window scale factor.
  rtc::FifoBuffer m_sbuf;

  // Maximum segment size, estimated protocol level, largest segment sent
  uint32_t m_mss, m_msslevel, m_largest, m_mtu_advise;
  // Retransmit timer
  uint32_t m_rto_base;

  // Timestamp tracking
  uint32_t m_ts_recent, m_ts_lastack;

  // Round-trip calculation
  uint32_t m_rx_rttvar, m_rx_srtt, m_rx_rto;

  // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
  uint32_t m_ssthresh, m_cwnd;
  uint8_t m_dup_acks;
  uint32_t m_recover;
  uint32_t m_t_ack;

  // Configuration options
  bool m_use_nagling;
  uint32_t m_ack_delay;

  // This is used by unit tests to test backward compatibility of
  // PseudoTcp implementations that don't support window scaling.
  bool m_support_wnd_scale;
};

}  // namespace cricket

#endif  // P2P_BASE_PSEUDOTCP_H_
