/*!
 * sprinklers.c
 *
 * Copyright (c) 2015, 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: 30/04/2015
 *
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <jsoncpp/json.h>
#include <string>

#include <ubuscpp/UBusCall.h>

#include "sprinklers.h"

/*-------------------------------- GLOBALES ---------------------------------*/


/*!  ----------------------------------------------------------------------------
 *  @fn sprinklers_setup
 *
 *  @brief this function setup the OSPI environement.
 */
int sprinklers_setup (void)
{
	UBusCall theCmd;
	std::string theResult;
	int theIDVal;

	fprintf (stderr, "Setup the Gpios used by the Sprinklers.\n");

	if (theCmd.Exec ("domo.capabilities.sprinklers", "get", "", theResult) == 0){

		// We get the the sprinklers. Get the IDs.
		Json::Reader theReader;
		Json::Value theRoot;
		Json::Value theElement;

		if (!theReader.parse (theResult, theRoot)) {

    		fprintf (stderr, "Failed parse the List of Sprinklers.\n");
    		return -1;
  		}

		for (const Json::Value& theElement : theRoot["Sprinklers"]) {

			theIDVal = theElement["id"].asInt();
			sprinkler_setup_station (theIDVal);
		}
	}

	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn sprinkler_setup_station
 *
 *  @brief This function change the State of an Ospi Station.
 */
int sprinkler_setup_station (int aStation)
{
	char theCommand[255];

	printf (" Setup the Station: %d\n", aStation);

	// Activate the Gpio
	sprintf (theCommand, "echo %d > /sys/class/gpio/export", aStation);
	system (theCommand);

	// Select the Direction of the Gpio
	sprintf (theCommand, "echo out > /sys/class/gpio/gpio%d/direction", aStation);
	system (theCommand);

	// Select the Direction of the Gpio
	sprintf (theCommand, "echo 1 > /sys/class/gpio/gpio%d/value", aStation);
	system (theCommand);

	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn sprinkler_set_station
 *
 *  @brief This function change the State of an Ospi Station.
 */
int sprinklers_set_station (uint32_t aStation, bool aState)
{
	FILE *theFp;
	char theGpioPath[255];
	
	sprintf (theGpioPath, "/sys/class/gpio/gpio%d/value", aStation);
	
	theFp = fopen (theGpioPath, "w");

	if (theFp == NULL) {

		fprintf (stderr, "Impossible to open: <%s>\n", theGpioPath);
		return -1;
	}

	if (aState) {

		fwrite ("0", 1, 1, theFp);
	}
	else {

		fwrite ("1", 1, 1, theFp);
	}	
	
	fclose (theFp);

	return 0;
}


/*!  ----------------------------------------------------------------------------
 *  @fn sprinkler_get_station
 *
 *  @brief This function change the State of an Ospi Station.
 */
int sprinklers_get_station (uint32_t aStation, bool &aState)
{
	FILE *theFp;
	char theGpioPath[255];
	char theData[5];

	fprintf (stdout, "get station state (%d)\n", aStation);

	sprintf (theGpioPath, "/sys/class/gpio/gpio%d/value", aStation);

	theFp = fopen (theGpioPath, "r");

	if (theFp == NULL) {

		fprintf (stderr, "Impossible to open: <%s>\n", theGpioPath);
		return -1;
	}

	fread (theData, 1, 1, theFp);

	//printf ("theData: %s\n", theData);

	if (theData[0] == '0') {
		aState = true;
	}
	else {
		aState = false;
	}

	fclose (theFp);

	return 0;
}


