<?php
	require_once "helpers.php";
	define("DB_NAME", $_SERVER['DOCUMENT_ROOT']."/configDB.db");
	define("TABLE_NAME", "tblConfig");
	if (!defined("HOST")) define("HOST", "http://" . htmlentities($_SERVER["HTTP_HOST"]));
	
	if(isset($_POST["action"]) && !empty($_POST["action"])) {
		$action = getPost("action");
		switch($action) {
			case 'readArray' :
				$values = array();
				$data = json_decode( getPost("data"), true);
				for ($i = 0; $i < count($data); $i++) {
					$values[$data[$i]["key"]] = readDB($data[$i]["section"],
						$data[$i]["key"]);
				}
				echo json_encode($values);
				break;
			case 'read' :
				$section = getPost("section");
				$key = getPost("key");
				$value = readDB($section, $key);
				echo $value;
				break;
			case 'readSection' :
				$section = getPost("section");
				$toLower = getPost("toLower");
				$results = readSection($section, $toLower);
				echo json_encode($results);
				break;
			case 'writeArray' :
				$data = json_decode( getPost("data") , true);
				$category = getPost("category");
				writeArray($data);
				alertProcessor($category);
				break;
			case 'write' :
				$section = htmlentities(getPost("section"));
				$key = htmlentities(getPost("key"));
				$value = getPost("value");
				$category = getPost("category");
				writeDB($section, $key, $value);
				if ($category != "") {
					alertProcessor($category);
				}
				break;
			case 'delete' :
				$section = htmlentities(getPost("section"));
				$key = htmlentities(getPost("key"));
				$category = getPost("category");
				deleteFromDB($section, $key);
				alertProcessor($category);
				break;
			case 'deleteSection' :
				$section = htmlentities(getPost("section"));
				If (deleteSection($section)) {echo "Success";}
				break;
		}
	}
	
	/**
	* Check database can be read
	**/
	function databaseIsReadable() {
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
			
			$STH = $DBH->prepare("SELECT * FROM '" . TABLE_NAME . "';");
			$STH->execute();
			return 1;
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return 0;
		}
	}
	
	/**
	 * Update database if row exists or insert new row 
	 * @param string $section The section field to write
	 * @param string $key The key field to write
	 * @param string $value The value field to write
	 **/
	function writeDB($section, $key, $value) {
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		try {
			$STH = $DBH->prepare("INSERT OR REPLACE INTO " . TABLE_NAME . " (id, section,
									key, value)
									VALUES (
										(SELECT id FROM " . TABLE_NAME . " WHERE (section LIKE
											:section AND key LIKE :key)),
										:section,
										:key,
										:value
									);"
								);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error in prepared statement.";
		}
		
		try {
			$STH->bindParam(':section', $section);
			$STH->bindParam(':key', $key);
			$STH->bindParam(':value', $value);
			$STH->execute();
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error writing to database.";
		}
		
		$DBH = null;
	}
	
	/**
	 * Update database
	 * @param array $data Array of section, key, value triplets to be written to the database
	 **/
	function writeArray($data) {
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		$STH = $DBH->prepare("
			INSERT OR REPLACE INTO " . TABLE_NAME . " (id, section, key, value)
			VALUES (
				(SELECT id FROM " . TABLE_NAME . " WHERE (section LIKE
					:section AND key LIKE :key)),
				:section,
				:key,
				:value
			);"
		);

		try {
			$DBH->beginTransaction();
			for ($i = 0; $i < count($data); $i++) {
				$STH->bindParam(':section', $data[$i]["section"]);
				$STH->bindParam(':key', $data[$i]["key"]);
				$STH->bindParam(':value', $data[$i]["value"]);
				$STH->execute();
			}
			$DBH->commit();
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error writing to database.";
		}
		
		$DBH = null;
	}
	
	/** 
	 * Read a value from the database
	 * @param string $section The section to read
	 * @param string $key The key to read
	 * @return string The value found in the database
	 **/
	function readDB($section, $key) {
	
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		try {
			$STH = $DBH->prepare("SELECT value FROM " . TABLE_NAME . "
									WHERE (section LIKE :section AND key LIKE :key)");
			$STH->setFetchMode(PDO::FETCH_ASSOC);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error in prepared statement.";
		}
		
		try {
			$STH->bindParam(':section', $section);
			$STH->bindParam(':key', $key);
			$STH->execute();
			$row = $STH->fetch();
			$value = $row['value'];
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error writing to database.";
		}
		
		$DBH = null;
		return $value;
	}
	
	/**
	 * Read all key value pairs for a given section
	 *@param string $section The section from which to read
	 **/
	function readSection($section, $toLower) {
		
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		try {
			$STH = $DBH->prepare("SELECT key, value FROM " . TABLE_NAME . "
									WHERE (section LIKE :section)
									AND (key IS NOT NULL)");
			$STH->setFetchMode(PDO::FETCH_ASSOC);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error in prepared statement.";
		}
		
		try {
			$STH->bindParam(':section', $section);
			$STH->execute();
			$value = array();
			while ($row = $STH->fetch()) {
				if ($toLower) {
					$key = strtolower($row['key']);
				} else {
					$key = ($row['key']);
				}
				//Empty unit serial numbers can write 0xFF into the database, which causes json_encode to fail
				//This filters them out
				if (strpos($key, chr(255)) === false) {
					$value[$key] = $row['value'];
				}
			}
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error reading from database.";
		}
		
		$DBH = null;
		return $value;
	}
	
	/**
	 *
	 *
	 **/
	function deleteFromDB($section, $key) {
		
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		try {
			$STH = $DBH->prepare("DELETE FROM " . TABLE_NAME . "
									WHERE (section LIKE :section AND key LIKE :key)");
			$STH->setFetchMode(PDO::FETCH_ASSOC);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error in prepared statement.";
		}
		
		try {
			$STH->bindParam(':section', $section);
			$STH->bindParam(':key', $key);
			$STH->execute();
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error deleting from database.";
		}
		
		$DBH = null;
		return true;
	}
	
	/**
	 * 
	 *
	 **/
	function deleteSection($section) {
		
		try {
			$DBH = new PDO("sqlite:" . DB_NAME);
			$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Unable to connect to database.";
		}
		
		try {
			$STH = $DBH->prepare("DELETE FROM " . TABLE_NAME . "
									WHERE section LIKE :section");
			$STH->setFetchMode(PDO::FETCH_ASSOC);
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error in prepared statement.";
		}
		
		try {
			$STH->bindParam(':section', $section);
			$STH->execute();
		} catch (PDOException $e) {
			file_put_contents('PDOErrors.txt', $e->getMessage(), FILE_APPEND);
			return "Error deleting from database.";
		}
		
		$DBH = null;
		return true;
	}
?>