/*!
 * Devices.cpp
 *
 * Copyright (c) 2016, 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 <fstream>

#include <jsoncpp/json.h>

#include "devices/Devices.h"


/*!  ----------------------------------------------------------------------------
 *  @fn Devices
 *
 *  @brief Constructor of the Devices Managagers.
 */
Devices::Devices (std::string aPath):
mFilePath (aPath)
{
}


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


/*!  ----------------------------------------------------------------------------
 *  @fn load
 *
 *  @brief Load the Devices from the Json File.
 */
int Devices::load (void)
{
	Json::Reader theReader;
	Json::Value theRoot;
	std::ifstream theDevicesFile (mFilePath.c_str());
	fprintf (stderr, "Devices::load...\n");
	
	/* Load and Parse the Json File. */
	if (!theReader.parse (theDevicesFile, theRoot)) {

		fprintf (stderr, "Failed to parse the Devices File (%s).\n",
				 mFilePath.c_str());
		return -1;
	}

	/* Open Lights. */
	mLights.load_from_json (theRoot["Lights"]);

	/* Open Shutters. */
	mShutters.load_from_json (theRoot["Shutters"]);

	/* Open Sprinklers. */
	mSprinklers.load_from_json (theRoot["Sprinklers"]);
	
	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn save
 *
 *  @brief Save the Devices from the Json File.
 */
int Devices::save (void)
{
	Json::StyledStreamWriter theWriter;
	
	Json::Value theRoot(Json::objectValue);
	fprintf (stderr, "Devices::Save...\n");

	theRoot["Lights"] = mLights.to_json();
	theRoot["Shutters"] = mShutters.to_json();
	theRoot["Sprinklers"] = mSprinklers.to_json();

	/* Save to the File. */
	std::ofstream theOutput (mFilePath.c_str());
	theWriter.write (theOutput, theRoot);
	
	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn get
 *
 *  @brief get the list of devices of a specific capabilities.
 */
std::string Devices::get (const std::string &aCapability)
{
	Json::StyledWriter theWriter;
	Json::Value theOutput;
	fprintf (stderr, "Devices::get...\n");
	
	if (aCapability == "Lights") {

		theOutput[aCapability] = mLights.to_json (true);
	}
	else if (aCapability == "Shutters") {

		theOutput[aCapability] = mShutters.to_json (true);
	}
	else if (aCapability == "Sprinklers") {

		theOutput[aCapability] = mSprinklers.to_json (true);
	}

	return theWriter.write (theOutput).c_str();
}


/*!  ----------------------------------------------------------------------------
 *  @fn set
 *
 *  @brief get the device of a specific capabilities, with the ID.
 */
int Devices::set (const std::string &aCapability, Json::Value anElement)
{
	int theResult = -1;

	if (aCapability == "Lights") {

		theResult = mLights.set (anElement);
	}
	else if (aCapability == "Shutters") {

		theResult = mShutters.set (anElement);
	}
	else if (aCapability == "Sprinklers") {

		theResult = mSprinklers.set (anElement);
	}

	if (theResult == 0)
		save ();

	return theResult;
}


/*!  ----------------------------------------------------------------------------
 *  @fn set
 *
 *  @brief get the device of a specific capabilities, with the ID.
 */
int Devices::set (const std::string &aCapability, int anID, bool aState)
{
	int theResult = -1;

	if (aCapability == "Lights") {

		theResult = mLights.set (anID, aState);
	}
	else if (aCapability == "Shutters") {

		theResult = mShutters.set (anID, aState);
	}
	else if (aCapability == "Sprinklers") {

		theResult = mSprinklers.set (anID, aState);
	}

	if (theResult == 0)
		save ();

	return theResult;
}
