/*
 * 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();

 private:
  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_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_
