/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkNetIO_DEFINED
#define SkNetIO_DEFINED

#include <netinet/in.h>
#include <sys/socket.h>
#include "SkTypes.h"
#include "SkStream.h"

/* PACKET and HEADER Format */
#define PACKET_SIZE 1024
#define HEADER_SIZE 20
#define CONTENT_SIZE 1004

#define DEFAULT_PORT 15555
#define MAX_WAITING_CLIENTS 3
#define NONBLOCKING_SOCKETS

class SkSocket {
public:
    SkSocket();
    virtual ~SkSocket();

    enum State {
        kError_state,
        kBegin_state,
        kIncomplete_state,
        kDone_state
    };

    enum DataType {
        kPipeAppend_type,
        kPipeReplace_type,
        kString_type,
        kInt_type
    };

    bool isConnected() { return fConnected; }
    /**
     * Write data to the socket. Data is a pointer to the beginning of the data
     * to be sent and dataSize specifies the number of bytes to send. This
     * method will spread the data across multiple packets if the data can't all
     * fit in a single packet. The method will write all the data to each of the
     * socket's open connections until all the bytes have been successfully sent
     * and return total the number of bytes written to all clients, unless there
     * was an error during the transfer, in which case the method returns -1.
     * For blocking sockets, write will block indefinitely if the socket at the
     * other end of the connection doesn't receive any data.
     * NOTE: This method guarantees that all of the data will be sent unless
     * there was an error, so it may block temporarily when the write buffer is
     * full
     */
    int writePacket(void* data, size_t size, DataType type = kPipeAppend_type);

    /**
     * Read a logical packet from socket. The data read will be stored
     * sequentially in the dataArray. This method will keep running until all
     * the data in a logical chunk has been read (assembling multiple partial
     * packets if necessary) and return the number of bytes successfully read,
     * unless there was an error, in which case the method returns -1. \For
     * nonblocking sockets, read will return 0 if there's nothing to read. For
     * blocking sockets, read will block indefinitely if the socket doesn't
     * receive any data.
     * NOTE: This method guarantees that all the data in a logical packet will
     * be read so it may block temporarily if it's waiting for parts of a
     * packet
     */
    int readPacket(void (*onRead)(int cid, const void* data, size_t size,
                                  DataType type, void*), void* context);

    /**
     * Suspend network transfers until resume() is called. Leaves all
     * connections in tact.
     */
    void suspendAll() { fReadSuspended = fWriteSuspended = true; }
    /**
     * Resume all network transfers.
     */
    void resumeAll() { fReadSuspended = fWriteSuspended = false; }
    /**
     * Other helper functions
     */
    void suspendRead() { fReadSuspended = true; }
    void resumeRead() { fReadSuspended = false; }
    void suspendWrite()  { fWriteSuspended = true; }
    void resumeWrite()  { fWriteSuspended = false; }

protected:
    struct header {
        bool        done;
        int         bytes;
        DataType    type;
    };

    /**
     * Create a socket and return its file descriptor. Returns -1 on failure
     */
    int createSocket();

    /**
     * Close the socket specified by the socket file descriptor argument. Will
     * update fMaxfd and working set properly
     */
    void closeSocket(int sockfd);

    /**
     * Called when a broken or terminated connection has been detected. Closes
     * the socket file descriptor and removes it from the master set by default.
     * Override to handle broken connections differently
     */
    virtual void onFailedConnection(int sockfd);

    /**
     * Set the socket specified by the socket file descriptor as nonblocking
     */
    void setNonBlocking(int sockfd);

    /**
     * Add the socket specified by the socket file descriptor to the master
     * file descriptor set, which is used to in the select() to detect new data
     * or connections
     */
    void addToMasterSet(int sockfd);

    bool    fConnected;
    bool    fReady;
    bool    fReadSuspended;
    bool    fWriteSuspended;
    int     fMaxfd;
    int     fPort;
    int     fSockfd;

    /**
     * fMasterSet contains all the file descriptors to be used for read/write.
     * For clients, this only contains the client socket. For servers, this
     * contains all the file descriptors associated with established connections
     * to clients
     */
    fd_set  fMasterSet;
};

/*
 * TCP server. Can accept simultaneous connections to multiple SkTCPClients and
 * read/write data back and forth using read/writePacket calls. Port number can
 * be specified, but make sure that client/server use the same port
 */
class SkTCPServer : public SkSocket {
public:
    SkTCPServer(int port = DEFAULT_PORT);
    virtual ~SkTCPServer();

    /**
     * Accept any incoming connections to the server, will accept 1 connection
     * at a time. Returns -1 on error. For blocking sockets, this method will
     * block until a client calls connectToServer()
     */
    int acceptConnections();

    /**
     * Disconnect all connections to clients. Returns -1 on error
     */
    int disconnectAll();
private:
    typedef SkSocket INHERITED;
};

/*
 * TCP client. Will connect to the server specified in the constructor. If a
 * port number is specified, make sure that it's the same as the port number on
 * the server
 */
class SkTCPClient : public SkSocket {
public:
    SkTCPClient(const char* hostname, int port = DEFAULT_PORT);

    /**
     * Connect to server. Returns -1 on error or failure. Call this to connect
     * or reconnect to the server. For blocking sockets, this method will block
     * until the connection is accepted by the server.
     */
    int connectToServer();
protected:
    /**
     * Client needs to recreate the socket when a connection is broken because
     * connect can only be called successfully once.
     */
    virtual void onFailedConnection(int sockfd);
private:
    sockaddr_in fServerAddr;
    typedef SkSocket INHERITED;
};

#endif
