/*!
 * Devices.cpp
 *
 * Copyright (c) 2016-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: 20/05/2016
 *
 */

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

#include <cstdio>

#include <json-c/json.h>
#include <json-c/json_util.h>

#include "domo.h"

#include "devices/devices-manager.h"

/*!  ----------------------------------------------------------------------------
 *  @fn DevicesManager
 *
 *  @brief Constructor of the Devices Managagers.
 */
DevicesManager::DevicesManager(const std::string &a_path) : m_file_path(a_path)
{
}

/*!  ----------------------------------------------------------------------------
 *  @fn ~DevicesManager
 *
 *  @brief Destructor of the Devices Managagers.
 */
DevicesManager::~DevicesManager(void)
{
}

/*!  ----------------------------------------------------------------------------
 *  @fn load
 *
 *  @brief Load the Devices from the Json File.
 */
int DevicesManager::load(void)
{
	struct json_object *the_root_node, *the_value_node;
	fprintf(stderr, "Devices::load...\n");

	the_root_node = json_object_from_file(m_file_path.c_str());
	if (the_root_node == NULL)
	{
		fprintf(stderr, "Failed to parse the Devices File (%s).\n", m_file_path.c_str());
		return -1;
	}

	if (json_object_object_get_ex(the_root_node, kLightEntry, &the_value_node))
	{
		printf(" On a des Lights.\n");
		m_lights.from_json(the_value_node);
	}

	if (json_object_object_get_ex(the_root_node, kShutterEntry, &the_value_node))
	{
		printf(" On a des shutters.\n");
		m_shutters.from_json(the_value_node);
	}

	if (json_object_object_get_ex(the_root_node, kSprinklerEntry, &the_value_node))
	{
		printf(" On a des sprintkler.\n");
		m_sprinklers.from_json(the_value_node);
	}

	/* Clean the json object. */
	json_object_put(the_root_node);

	return 0;
}

/*!  ----------------------------------------------------------------------------
 *  @fn save
 *
 *  @brief Save the Devices from the Json File.
 */
int DevicesManager::save(void)
{
	int the_result;
	struct json_object *the_root_node;

	the_root_node = json_object_new_object();

	// Lights
	json_object_object_add(the_root_node, kLightEntry, m_lights.to_json());
	// Shutters
	json_object_object_add(the_root_node, kShutterEntry, m_shutters.to_json());
	// Sprinklers
	json_object_object_add(the_root_node, kSprinklerEntry, m_sprinklers.to_json());

	the_result = json_object_to_file(m_file_path.c_str(), the_root_node);

	/* Clean the json object. */
	json_object_put(the_root_node);

	return the_result;
}

/*!  ----------------------------------------------------------------------------
 *  @fn get
 *
 *  @brief get the list of devices of a specific capabilities.
 */
std::string DevicesManager::get(const std::string &a_capability)
{
	std::string the_output;
	struct json_object *the_output_node;
	fprintf(stderr, "Devices::get...\n");

	the_output_node = json_object_new_object();

	if (a_capability == kLightEntry)
	{
		json_object_object_add(the_output_node, kLightEntry, m_lights.to_json());
	}
	else if (a_capability == kShutterEntry)
	{

		json_object_object_add(the_output_node, kShutterEntry, m_shutters.to_json());
	}
	else if (a_capability == kSprinklerEntry)
	{

		json_object_object_add(the_output_node, kSprinklerEntry, m_sprinklers.to_json());
	}

	the_output = json_object_to_json_string(the_output_node);

	json_object_put(the_output_node);

	return the_output;
}

/*!  ----------------------------------------------------------------------------
 *  @fn set
 *
 *  @brief set the device from a specific capabilities, with the given json.
 */
int DevicesManager::set(const std::string &a_capability, struct json_object *a_node)
{
	int the_result = -1;

	if (a_capability == kLightEntry)
	{
		the_result = m_lights.set(a_node);
	}
	else if (a_capability == kShutterEntry)
	{
		the_result = m_shutters.set(a_node);
	}
	else if (a_capability == kSprinklerEntry)
	{
		the_result = m_sprinklers.set(a_node);
	}

	if (the_result == 0)
		save();

	return the_result;
}

/*!  ----------------------------------------------------------------------------
 *  @fn set_state
 *
 *  @brief set the state for device with the id from a specific capabilitiy.
 */
int DevicesManager::set_state(const std::string &a_capability, int an_id, bool a_state)
{
	int the_result = -1;

	if (a_capability == kLightEntry)
	{
		the_result = m_lights.set(an_id, a_state);
	}
	else if (a_capability == kShutterEntry)
	{
		the_result = m_shutters.set(an_id, a_state);
	}
	else if (a_capability == kSprinklerEntry)
	{
		the_result = m_sprinklers.set(an_id, a_state);
	}

	if (the_result == 0)
	{
		save();
	}

	return the_result;
}
