/*
 * libjingle
 * Copyright 2004--2005, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products 
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef TALK_P2P_BASE_PSEUDOTCP_H_
#define TALK_P2P_BASE_PSEUDOTCP_H_

#include <list>

#include "talk/base/basictypes.h"

namespace cricket {

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

class PseudoTcp;

class IPseudoTcpNotify {
 public:
  virtual ~IPseudoTcpNotify() {}
  // 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 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;
};

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

class PseudoTcp {
 public:
  static uint32 Now();

  PseudoTcp(IPseudoTcpNotify* notify, uint32 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 mtu);

  // Call this based on timeout value returned from GetNextClock.
  // It's ok to call this too frequently.
  void NotifyClock(uint32 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 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.
  enum Option {
    OPT_NODELAY,      // Whether to enable Nagle's algorithm (0 == off)
    OPT_ACKDELAY,     // The Delayed ACK timeout (0 == off).
    //kOptRcvBuf,     // Set the receive buffer size, in bytes.
    //kOptSndBuf,     // Set the send buffer size, in bytes.
  };
  void GetOption(Option opt, int* value);
  void SetOption(Option opt, int value);

 protected:
  enum SendFlags { sfNone, sfDelayedAck, sfImmediateAck };
  enum {
    // Note: can't go as high as 1024 * 64, because of uint16 precision
    kRcvBufSize = 1024 * 60,
    // Note: send buffer should be larger to make sure we can always fill the
    // receiver window
    kSndBufSize = 1024 * 90
  };

  struct Segment {
    uint32 conv, seq, ack;
    uint8 flags;
    uint16 wnd;
    const char * data;
    uint32 len;
    uint32 tsval, tsecr;
  };

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

  struct RSegment {
    uint32 seq, len;
  };

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

  IPseudoTcpNotify::WriteResult packet(uint32 seq, uint8 flags,
                                       const char* data, uint32 len);
  bool parse(const uint8* buffer, uint32 size);

  void attemptSend(SendFlags sflags = sfNone);

  void closedown(uint32 err = 0);

  bool clock_check(uint32 now, long& nTimeout);

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

  void adjustMTU();

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

 private:
  // Get the total number of bytes of free space in m_rbuf, consecutive or not.
  uint32 getReceiveBufferSpace() const;

  // Get the number of bytes that can be written to m_rbuf.
  uint32 getReceiveBufferConsecutiveSpace() const;

  // Consolidate free space in m_rbuf so that it is a consecutive segment.
  void consolidateReceiveBufferSpace();

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

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

  // Incoming data
  typedef std::list<RSegment> RList;
  RList m_rlist;
  char m_rbuf[kRcvBufSize];
  uint32 m_rcv_nxt, m_rcv_wnd, m_rpos, m_rlen, m_lastrecv;

  // Outgoing data
  SList m_slist;
  char m_sbuf[kSndBufSize];
  uint32 m_snd_nxt, m_snd_wnd, m_slen, m_lastsend, m_snd_una;
  // Maximum segment size, estimated protocol level, largest segment sent
  uint32 m_mss, m_msslevel, m_largest, m_mtu_advise;
  // Retransmit timer
  uint32 m_rto_base;

  // Timestamp tracking
  uint32 m_ts_recent, m_ts_lastack;

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

  // Congestion avoidance, Fast retransmit/recovery, Delayed ACKs
  uint32 m_ssthresh, m_cwnd;
  uint8 m_dup_acks;
  uint32 m_recover;
  uint32 m_t_ack;

  // Configuration options
  bool m_use_nagling;
  uint32 m_ack_delay;
};

}  // namespace cricket

#endif  // TALK_P2P_BASE_PSEUDOTCP_H_
