/*
 * connected_client_obj.h
 *
 *  Created on: 02 Oct 2014
 *      Author: Stephan Krynauw
 */

#ifndef CONNECTED_CLIENT_OBJ_H_
#define CONNECTED_CLIENT_OBJ_H_
#include <string.h>
#include <sys/socket.h>
#include <pthread.h>
#include <klog.h>

#include "thread_safe_queue.h"
#include "daemon_obj.h"

/**
 * Object which facilitates tcp connection between a client which has connected
 *
 * This object is actually the "server" but is a object which references to a client
 */
class ConnectedClientObj
{
  public:
    ConnectedClientObj(int _client_socket, DaemonObj* _daemon_obj);
    /**
     * Starts up all the threads
     *  1) RxListenerThread
     *  2) RxServicerThread
     *  3) TxSerivcerThread
     */
    void StartClient();
    void StopClient() {
      m_running = false;
    }

    bool IsActive() {
      return m_running;
    }

    void SetDaemonObj(DaemonObj* _daemon_obj) {
      m_daemon_obj = _daemon_obj;
    }

    virtual ~ConnectedClientObj();
  private:

    /**
     * Method to start RxListenerThread
     * @param args
     */
    static void * RxListenerCaller(void *_arg) {
      ((ConnectedClientObj*) _arg)->RxListenerThread();
      return NULL;
    }

    /**
     * Thread which listens for msg's from the client
     * @param args
     */
    void RxListenerThread();

    /**
     * Method to start RxServicerThread
     * @param args
     */
    static void * RxServicerCaller(void *_arg) {
      ((ConnectedClientObj*) _arg)->RxServicerThread();
      return NULL;
    }

    /**
     * Thread which services the rx_queue
     *
     * Each msg in the queue is sent to the power_meter_obj
     * and waits for a reply, then pushes reply onto the tx_queue
     */
    void RxServicerThread();

    /**
     * Method to start TxServicerThread
     * @param args
     */
    static void * TxServicerCaller(void *_arg) {
      ((ConnectedClientObj*) _arg)->TxServicerThread();
      return NULL;
    }

    /**
     * Thread which services the tx_queue
     *
     * Each msg in the queue is sent to the connected client
     */
    void TxServicerThread();

    ConnectedClientObj* m_instance;
    DaemonObj* m_daemon_obj;

    /**
     * Thread id's
     */
    pthread_t m_rx_listener_thread_id;
    pthread_t m_rx_servicer_thread_id;
    pthread_t m_tx_servicer_thread_id;
    int m_client_socket;

    /**
     * -msg_queues for rx and tx msgs
     */
    ThreadSafeQueue* m_rx_queue;
    ThreadSafeQueue* m_tx_queue;

    bool m_running;
};

#endif /* CONNECTED_CLIENT_OBJ_H_ */
