/*
 * Copyright (C) 2015 by the University of Southern California
 * $Id: client.hh 24038 2015-05-17 03:00:48Z liangzhu $
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
 * 
 */

#ifndef CLIENT_HH
#define CLIENT_HH

#include <netinet/in.h>
#include <event2/bufferevent.h>
#include <openssl/ssl.h>
#include "safe_queue.hh"
#include "safe_map.hh"
#include "net_msg.hh"

enum {CONN_NONE, CONN_UDP, CONN_TCP, CONN_TLS};

enum {STAT_NEW, STAT_SENT, STAT_WAIT, STAT_RESP, STAT_UPGRADE};

class client_t {
public:
  client_t(uint8_t, int, struct sockaddr *, socklen_t,
	   struct bufferevent *, struct event_base *,
	   safe_map<int, client_t *> *,
	   safe_queue<int> *id_q, int);
  client_t(client_t *, uint8_t *, size_t);
  client_t();
  ~client_t();
  void copy_addr(struct sockaddr *, socklen_t);
  void enq_send(uint8_t *, size_t);
  void enq_recv(uint8_t *, size_t);
  void copy(client_t *);
  
  uint8_t type;          // tcp? tls?
  uint8_t status;

  int svr_fd;            // recursive server fd
  int s;                 // its own socket
  SSL_CTX *svr_ctx;      // server ssl
  SSL *ctx;              // client ssl
  
  struct sockaddr *addr; // client address
  socklen_t addr_len;

  struct bufferevent *bev;
  struct event_base *base;
  
  safe_queue<int> *id_q;
  safe_map<int, client_t *> *map;

  safe_map<uint16_t, uint16_t> *id_map;

  safe_queue<net_msg *> *recv_q; //received message queue
  safe_queue<net_msg *> *send_q; //message to send back to client

  net_msg *pending_msg;

private:
  void init();
};

#endif //CLIENT_HH

