/*!
 * Copyright (c) 2015-2018, NADAL Jean-Baptiste. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA
 *
 * @Author:  NADAL Jean-Baptiste
 * @Date: 23/06/2017
 */

/*------------------------------- INCLUDES ----------------------------------*/

extern "C" {
#include <libubox/ustream.h>
}

#include <uhttpd/uhttpd.h>
#include <uhttpd/plugin.h>

#include "core/http-reason.h"

#include "notification/notification-controller.h"
#include "notification/notification-connection.h"

#define kdefaultTimeout 20000

/*!  ----------------------------------------------------------------------------
 *  @fn NotificationConnection
 *
 *  @brief constructor of the notification connection object.
 */
NotificationConnection::NotificationConnection(struct uhttpd_ops *an_ops, struct client *a_client, NotificationController *a_controller) : WebConnection(an_ops, a_client),
																																		   m_controller(a_controller),
																																		   m_ctx(NULL)
{
	// printf("constructor NotificationConnection : %p\n", this);
}

/*!  ----------------------------------------------------------------------------
 *  @fn ~NotificationConnection
 *
 *  @brief destructor of the notification controller object.
 */
NotificationConnection::~NotificationConnection(void)
{
	//printf("destructor NotificationConnection : %p\n", this);
	stop();
	if (m_ctx != NULL)
	{
		unregister_event(m_ctx);
	}
}

/*!  ----------------------------------------------------------------------------
 *  @fn invoke
 *
 *  @brief invoke an async connection.
 */
void NotificationConnection::invoke(struct ubus_context *a_ctx)
{
	m_ctx = a_ctx;

	register_event(m_ctx, m_controller->get_path());

	m_ops->http_header(m_client, 200, HttpReason::get(200).c_str());
	ustream_printf(m_client->us, "Content-Type: application/json\r\n");
	start(kdefaultTimeout, true);
}

/*!  ----------------------------------------------------------------------------
 *  @fn handle_event
 *
 *  @brief method called when a registered event is arrived for this connection.
 */
void NotificationConnection::handle_event(const char *a_type, const char *a_json_msg)
{
	// printf("NotificationConnection::handle_event\n");
	stop();
	m_ops->chunk_printf(m_client, "%s", a_json_msg);
	start(kdefaultTimeout, true);
}

/*!  ----------------------------------------------------------------------------
 *  @fn expire
 *
 *  @brief method called when no data is arrived to the notification canal.
 */
int NotificationConnection::expire(void)
{
	// printf ("NotificationConnection::expire\n");
	m_ops->chunk_printf(m_client, "{}");

	return 0;
}
