/*
 *  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 WEBRTC_BASE_ASYNCTCPSOCKET_H_
#define WEBRTC_BASE_ASYNCTCPSOCKET_H_

#include "webrtc/base/asyncpacketsocket.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/socketfactory.h"

namespace rtc {

// Simulates UDP semantics over TCP.  Send and Recv packet sizes
// are preserved, and drops packets silently on Send, rather than
// buffer them in user space.
class AsyncTCPSocketBase : public AsyncPacketSocket {
 public:
  AsyncTCPSocketBase(AsyncSocket* socket, bool listen, size_t max_packet_size);
  virtual ~AsyncTCPSocketBase();

  // Pure virtual methods to send and recv data.
  virtual int Send(const void *pv, size_t cb,
                   const rtc::PacketOptions& options) = 0;
  virtual void ProcessInput(char* data, size_t* len) = 0;
  // Signals incoming connection.
  virtual void HandleIncomingConnection(AsyncSocket* socket) = 0;

  virtual SocketAddress GetLocalAddress() const;
  virtual SocketAddress GetRemoteAddress() const;
  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
                     const rtc::PacketOptions& options);
  virtual int Close();

  virtual State GetState() const;
  virtual int GetOption(Socket::Option opt, int* value);
  virtual int SetOption(Socket::Option opt, int value);
  virtual int GetError() const;
  virtual void SetError(int error);

 protected:
  // Binds and connects |socket| and creates AsyncTCPSocket for
  // it. Takes ownership of |socket|. Returns NULL if bind() or
  // connect() fail (|socket| is destroyed in that case).
  static AsyncSocket* ConnectSocket(AsyncSocket* socket,
                                    const SocketAddress& bind_address,
                                    const SocketAddress& remote_address);
  virtual int SendRaw(const void* pv, size_t cb);
  int FlushOutBuffer();
  // Add data to |outbuf_|.
  void AppendToOutBuffer(const void* pv, size_t cb);

  // Helper methods for |outpos_|.
  bool IsOutBufferEmpty() const { return outpos_ == 0; }
  void ClearOutBuffer() { outpos_ = 0; }

 private:
  // Called by the underlying socket
  void OnConnectEvent(AsyncSocket* socket);
  void OnReadEvent(AsyncSocket* socket);
  void OnWriteEvent(AsyncSocket* socket);
  void OnCloseEvent(AsyncSocket* socket, int error);

  scoped_ptr<AsyncSocket> socket_;
  bool listen_;
  char* inbuf_, * outbuf_;
  size_t insize_, inpos_, outsize_, outpos_;

  DISALLOW_EVIL_CONSTRUCTORS(AsyncTCPSocketBase);
};

class AsyncTCPSocket : public AsyncTCPSocketBase {
 public:
  // Binds and connects |socket| and creates AsyncTCPSocket for
  // it. Takes ownership of |socket|. Returns NULL if bind() or
  // connect() fail (|socket| is destroyed in that case).
  static AsyncTCPSocket* Create(AsyncSocket* socket,
                                const SocketAddress& bind_address,
                                const SocketAddress& remote_address);
  AsyncTCPSocket(AsyncSocket* socket, bool listen);
  virtual ~AsyncTCPSocket() {}

  virtual int Send(const void* pv, size_t cb,
                   const rtc::PacketOptions& options);
  virtual void ProcessInput(char* data, size_t* len);
  virtual void HandleIncomingConnection(AsyncSocket* socket);

 private:
  DISALLOW_EVIL_CONSTRUCTORS(AsyncTCPSocket);
};

}  // namespace rtc

#endif  // WEBRTC_BASE_ASYNCTCPSOCKET_H_
