<?php
/*
This file does the following
	1. Generate folder structure in Inputs folder for each dynamic attribute
	   which has input_method of Online or File Exchange
	2. Put FetchData programs for each of above dynamic attribute in task scheduler
	3. Set Dynamic.status to time user pressed start button
*/
require '../Common/openDB.php';
require '../Common/preferences.php';

// Connect to DB
$con = mysql_connect($website,$userid,$pw);
if (!$con) {
	die('Could not connect: ' . mysql_error());
}
mysql_query("SET foreign_key_checks = 0",$con);

$curDB = "../CurrentlyOpenedDBName.tmp";
if(file_exists ($curDB)){
	$f = fopen($curDB, "r");
	$dbase   = trim(fgets($f)); // linked database name
	fclose($f);
	mysql_select_db($dbase, $con);
	//echo "Connected to " . $dbase . "<br/>";
}else{
	WarnUser("No database currently open","../Projects.html");
}

// JBI write time user pressed start


//if($debug)echo ("<script>  document.write(document.URL); </script>");

// User pressed stop so stop all data fetch processes
if($_GET[started] == "no"){
	$resA = mysql_query("SELECT COUNT(source_id)FROM Source",$con);
	while ($rowA = mysql_fetch_array(($resA)))$Nsource = $rowA[0];
	if($Nsource > 0){
		$res = mysql_query("SELECT COUNT(dynamic_id) FROM Dynamic",$con);
		while ($row = mysql_fetch_array($res))$NDynamic = $row[0];
		if($NDynamic > 0){
			$res = mysql_query("SELECT dynamic_id,fetcher_id,source_id,attribute FROM Dynamic",$con);
			while ($row = mysql_fetch_array($res)){
				$dynamic_id = $row[0];
				$fetcher_id = $row[1];

				mysql_query("UPDATE Dynamic SET status='stopped' WHERE dynamic_id = {$dynamic_id}",$con);

				$resA = mysql_query("SELECT input_method FROM Fetcher WHERE fetcher_id = {$fetcher_id}",$con);
				while($rowA = mysql_fetch_array($resA)){
					$input_method = $rowA[0];
					if($input_method == "File Exchange" || $input_method == "Online"){
						$DIDDB = $dynamic_id.$dbase;
						if($oper_sys == "windows"){
							shell_exec("schtasks.exe /delete /f /tn {$DIDDB}");
							if(file_exists($DIDDB.".bat"))unlink($DIDDB.".bat");
							if(file_exists($DIDDB.".vbs"))unlink($DIDDB.".vbs");
						}elseif($oper_sys == "linux"){
							rm_from_cron($DIDDB.".bash");
							unlink($DIDDB.".bash");
						}
						if(file_exists($DIDDB.".args"))unlink($DIDDB.".args");
						if(file_exists($DIDDB))unlink($DIDDB);
						if(file_exists($DIDDB.".lock"))unlink($DIDDB.".lock");
						if(file_exists($DIDDB.".sql"))unlink($DIDDB.".sql"); // may not have been created by FetchDataCron.php yet
					}
				}
			}
		}
	}

	// Now stop MDF

	echo("<form action='RightTop.php?started=no' method='post'>Data fetch has stopped<button type='submit'>OK</button></form>");
	goto end_fiddb;
	exit;
}

// Make folders to hold input data and call fetching bat file (that calls FetchData.php)
if(!file_exists("../../Inputs/{$dbase}"))mkdir("../../Inputs/{$dbase}");

$feedbackGiven = false;
$atLeastOneFetchON = false;

$resA = mysql_query("SELECT COUNT(source_id)FROM Source",$con);
while ($rowA = mysql_fetch_array(($resA)))$Nsource = $rowA[0];

if($Nsource > 0){
	$resA = mysql_query("SELECT source_id,name FROM Source",$con);
	while ($rowA = mysql_fetch_array(($resA))){
		$source_id = $rowA[0];
		$nameSrc = $rowA[1];
		$name_dir = preg_replace('/\s+/', '_', $nameSrc);

		$DID_dir = "../../Inputs/{$dbase}/{$name_dir}_{$source_id}";
		// replace spaces with underscore
		$DID_dir = preg_replace('/\s+/', '_', $DID_dir);
		//echo($DID_dir);
		if(!file_exists($DID_dir))mkdir($DID_dir);

		$res = mysql_query("SELECT COUNT(dynamic_id) FROM Dynamic WHERE source_id = {$source_id}",$con);
		while ($row = mysql_fetch_array($res))$NDynamic = $row[0];
		if($NDynamic > 0){

			$res = mysql_query("SELECT dynamic_id,fetcher_id,source_id,attribute,fetch_status,MDF_status FROM Dynamic WHERE source_id = {$source_id}",$con);
			while ($row = mysql_fetch_array($res)){
				$dynamic_id = $row[0];
				$fetcher_id = $row[1];
				$source_id = $row[2];
				$attribute = $row[3];
				$fetch_status = $row[4];
				$MDF_status = $row[5];

				// Set button to keep showing start if not even one DID is switched to fetch data
				if(!$atLeastOneFetchON && $fetch_status == "green")$atLeastOneFetchON = true;

				// Do not go on with this loop if not fetching data or fetching data via MDF
				if($fetch_status == "red")continue;
				if($MDF_status == "MDF")continue;
				$att_dir = preg_replace('/\s+/', '_', $attribute);

				if(!file_exists("../../Inputs/{$dbase}/{$name_dir}_{$source_id}/{$att_dir}_{$dynamic_id}"))mkdir("../../Inputs/{$dbase}/{$name_dir}_{$source_id}/{$att_dir}_{$dynamic_id}");

				if($fetcher_id == NULL){
					echo ("No fetcher associated with {$attribute} of entity {$nameSrc} <br/>");
				}else{

					// Select fetcher for each dynamic attribute for each source
					$argname = array();
					$resB = mysql_query("SELECT fetcher_id,frequency_id,name,input_method,EG_source,EG_user,EG_password,EG_destination,
					EG_appdestinationLocal,EG_appdestinationRemote,EG_IP,EG_file,EG_fetchfile,EG_fetchpath,EG_ftp,EG_duration,EG_frequency,expected_data_items
					FROM Fetcher WHERE fetcher_id = {$fetcher_id}",$con);
					while ($rowB = mysql_fetch_array($resB)){
						$fetcher_id     = $rowB[0];
						$frequency_id   = $rowB[1];
						$nameFet        = $rowB[2];
						$input_method   = $rowB[3];
						$EG_source 			= $rowB[4]; $argname[4] = "EG_source";
						$EG_user 			  = $rowB[5]; $argname[5] = "EG_user";
						$EG_password 		= $rowB[6]; $argname[6] = "EG_password";
						$EG_destination = $rowB[7]; $argname[7] = "EG_destination";
						$EG_appdestinationLocal 	= $rowB[8]; $argname[8] = "EG_appdestinationLocal";
						$EG_appdestinationRemote 	= $rowB[9]; $argname[9] = "EG_appdestinationRemote";
						$EG_IP 				  = $rowB[10]; $argname[10] = "EG_IP";
						$EG_file 			  = $rowB[11]; $argname[11] = "EG_file";
						$EG_fetchfile 	= $rowB[12]; $argname[12] = "EG_fetchfile";
						$EG_fetchpath 	= $rowB[13]; $argname[13] = "EG_fetchpath";
						$EG_ftp 			  = $rowB[14]; $argname[14] = "EG_ftp";
						$EG_duration 		= $rowB[15]; $argname[15] = "EG_duration"; // Reset in code below
						$EG_frequency 	= $rowB[16]; $argname[16] = "EG_frequency";
						$expected_items	= $rowB[17]; $argname[17] = "expected_items";

						if($input_method != "Manual"){
							if($frequency_id == NULL){
								echo ("Warning no frequency linked with fetcher {$nameFet} associated with {$attribute} of entity {$nameSrc} <br/>");
							}else{
								$resC = mysql_query("SELECT period,times_per_period,start,stop FROM Frequency WHERE frequency_id = {$frequency_id}",$con);
								while($rowC = mysql_fetch_array($resC)){
									$period = $rowC[0];
									$times_per_period = $rowC[1];
									$period_units = $times_per_period; // number of periods i.e. for 10 minutes period = minutes and period_units = 10
									$start_time = $rowC[2];
									$stop_time = $rowC[3];
									$EG_duration = GetTimePeriod($period,$times_per_period);
									$rowB[15] = $EG_duration;
								}

								//******************************************************************
								//******************************************************************
								// Following code to place call to entget using schtasks.exe or crontab
								// Notes for using this scheduler:
								// > 	valid time period switches are MINUTE, HOURLY, DAILY, WEEKLY, MONTHLY
								// > 	Monthly runs on the 1st of every month at the time button is pressed and cannot run every n months (i.e. has to run every 1 month)
								// 		the /mo modifier causes it to run in that month number i.e. /mo 8 will run on 1st August
								// > 	weekly -- /mo 2 for example will run every 2 weeks at the time button is pressed
								// > 	daily -- /mo 6 for example will run every 6 days at the time button is pressed
								//
								// Start time is an optional input
								// If daily, hourly or minutely are selected then day(s) to run on may be input

								$FetchTimePeriod = GetTimePeriod($period,$times_per_period) / 60;
								$DIDDB = $dynamic_id.$dbase;

								// If input method is fileX then poll directory based on prescribed times
								// this may be different from the time period of the associated frequency
								if ($input_method == "File Exchange"){
									if($FetchTimePeriod <= 15 * 60){ 			// if less than 15 minutes poll every minute
										$FetchTimePeriod = 1 * 60;
									}elseif($FetchTimePeriod <= 60 * 60){		// if less than 60 minutes poll every 15 minutes
										$FetchTimePeriod = 15 * 60;
									}else{
										$FetchTimePeriod = 60 * 60;				// if more than 60 minutes poll every hour
									}
								}
								if($oper_sys == "windows"){
									// 1. Make DIDDB.vbs
									FileCopier("DIDDB.vbs",$DIDDB.".vbs","FDC",$DIDDB);
									// 2. Make DIDDB.bat
									FileCopier("DIDDB.bat",$DIDDB.".bat","FDC",$DIDDB);
								}elseif($oper_sys == "linux"){
									$path_str = shell_exec("pwd");
									$path_str = trim($path_str);
									FileCopier("DIDDB.bash","tmpfile","FDC",$DIDDB);
									FileCopier("tmpfile",$DIDDB.".bash","PWD",$path_str);
								}

								// 3. Make DIDDB.args args list replacing \ with / and escaping space and simple bracket() characters
								// There is only one variable per line in this file in the order
								// line# 	entry
								// 1		dynamic_id
								// 2		database name
								// 3 		source_name
								// 4		attribute name
								// 5 		input_method
								// 6		rowB[4] defined above
								// 7		rowB[5] defined above...

								$argl = fopen($DIDDB.".args","w") or die ("Could not open $argl from AppendData for writing");
								fwrite($argl,"dynamic_id {$dynamic_id}\n");
								fwrite($argl,"dbase {$dbase}\n");
								fwrite($argl,"source_name {$nameSrc}\n");
								fwrite($argl,"attribute {$attribute}\n");
								fwrite($argl,"input_method {$input_method}\n");
								for($a = 4; $a <= 17; $a++){
									if($rowB[$a] != NULL){
										$repstr = str_replace("\\","/",$rowB[$a]);
										fwrite($argl,$argname[$a] . " " . $repstr . "\n");
									}
								}
								fclose($argl);

								// 4. Get frequency and when to run data fetch
								$command = GetSchedulerCmd($frequency_id, $TimeZone, $dynamic_id, $dbase, $con, $oper_sys);
								if($oper_sys == "windows"){
                  // The following may be a way to not show DOS command line in windows OS -- needs more investigation
                  //$path_str = "\" \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.vbs\\\"  \""; // works retain this

									if(file_exists("C:\\Program Files (x86)\\Ampps\\www\\EnTrak\\EnTrak\\2_Projects")){
										// The following works but displays window when fetching data
										$path_str = "\"cscript \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.vbs\\\"  \""; // works retain this
									}elseif(file_exists("C:\\Program Files\\Ampps\\www\\EnTrak\\EnTrak\\2_Projects")){
										$path_str = "\"cscript \\\"C:\Program Files\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.vbs\\\"  \""; // works retain this
									}else{
										echo "<h1> Error: AppendData.php WAMP server not found";
										exit;
									}

									//$path_str = "\"cmd.exe /c start /min \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.bat\\\" \"";
									// does not work
									//$path_str = "\"start /B cscript.exe \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.vbs\\\"  \"";
									// run bat file directly
									//$path_str = "\"start /MIN \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$dynamic_id}{$dbase}.bat\\\"\"";
									$command .= " /tr " . $path_str;

								}elseif($oper_sys == "linux"){
									$command = str_replace("<br/>"," bash {$path_str}/{$DIDDB}.bash \n",$command);

									// Skip this DID if not to be fetched
									if($fetch_status != "red")add_to_cron($command);
								}

								//echo $command . "<br/>";
								if($fetch_status != "red")$output = shell_exec($command);
								//echo $output . "<br/>";

								// End code to call entget
								//***************************************************
								//***************************************************

								// Pass back information to display stop button now
								$tmp_str = date('Y-m-d H:i:s');
								if($fetch_status != "red")mysql_query("UPDATE Dynamic SET status='{$tmp_str}' WHERE dynamic_id = {$dynamic_id}",$con);
								if(!$feedbackGiven){
									$feedbackGiven = true;
								}
							}
						}
					}
				}
			}
		}
	}
}

// Get any MDF Fetchers
$res = mysql_query("SELECT fetcher_id,name,description,frequency_id,EG_appdestinationLocal,EG_user,EG_password,EG_IP FROM Fetcher WHERE SUBSTRING(name,1,3) = 'MDF'",$con);
while($row = mysql_fetch_array($res)){
	$fetcher_id = $row[0];
	$FID = $fetcher_id . "MDF";
	$FIDDB = $fetcher_id . "MDF" . $dbase;
	$name = substr($row[1],3);;
	$description = $row[2];
	$frequency_id = $row[3];
	$local_app = trim($row[4]);
	$EG_user = $row[5];
	$EG_password = $row[6];
	$EG_IP = $row[7];

	if(!file_exists("../../Inputs/{$dbase}/MDF"))mkdir("../../Inputs/{$dbase}/MDF");
	if(!file_exists("../../Inputs/{$dbase}/MDF/{$name}"))mkdir("../../Inputs/{$dbase}/MDF/{$name}");

	// BuildAx MDF
	if($frequency_id == NULL){
		echo ("Warning no frequency linked with MDF fetcher {$name} <br/>");
	}else{
		$resC = mysql_query("SELECT period,times_per_period,start,stop FROM Frequency WHERE frequency_id = {$frequency_id}",$con);
		while($rowC = mysql_fetch_array($resC)){
			$period = $rowC[0];
			$times_per_period = $rowC[1];
			$period_units = $times_per_period; // number of periods i.e. for 10 minutes period = minutes and period_units = 10
			$start_time = $rowC[2];
			$stop_time = $rowC[3];
			$EG_duration = GetTimePeriod($period,$times_per_period);
		}
	}
	// make wrappers
	if($oper_sys == "windows"){
		// 1. Make DIDDB.vbs
		FileCopier("DIDDB.vbs",$FIDDB.".vbs","FDC",$FIDDB);
		// 2. Make DIDDB.bat
		FileCopier("FIDDB.bat",$FIDDB.".bat","FDC",$FIDDB);
	}elseif($oper_sys == "linux"){
		$path_str = shell_exec("pwd");
		$path_str = trim($path_str);
		FileCopier("FIDDB.bash","tmpfile","FDC",$FIDDB);
		FileCopier("tmpfile",$FIDDB.".bash","PWD",$path_str);
	}

	// Make FIDDB.args args list replacing \ with / and escaping space and simple bracket() characters
	// this file is created similar to DIDDB.args above
	$argl = fopen($FIDDB.".args","w") or die ("Could not open $argl from AppendData for writing");
	fwrite($argl,"dbase,{$dbase}\n");
	fwrite($argl,"fetcher_id,{$fetcher_id}\n");
	fwrite($argl,"fetcher_name,{$name}\n");
	fwrite($argl,"local_app,{$local_app}\n");
	fwrite($argl,"description,{$description}\n");
	fwrite($argl,"EG_user,{$EG_user}\n");
	fwrite($argl,"EG_password,{$EG_password}\n");
	fwrite($argl,"EG_IP,{$EG_IP}\n");
	fclose($argl);

	//Get frequency and when to run data fetch
	$command = GetSchedulerCmd($frequency_id, $TimeZone, $FID, $dbase, $con, $oper_sys);
	if($oper_sys == "windows"){
		if(file_exists("C:\\Program Files (x86)\\Ampps\\www\\EnTrak\\EnTrak\\2_Projects")){
			// The following works but displays window when fetching data
			$path_str = "\"cscript \\\"C:\Program Files (x86)\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$FIDDB}.vbs\\\"  \""; // works retain this
		}elseif(file_exists("C:\\Program Files\\Ampps\\www\\EnTrak\\EnTrak\\2_Projects")){
			$path_str = "\"cscript \\\"C:\Program Files\\\Ampps\www\EnTrak\EnTrak\\2_Projects\\{$FIDDB}.vbs\\\"  \""; // works retain this
		}else{
			echo "<h1> Error: AppendData.php WAMP server not found";
		}

		$command .= " /tr " . $path_str;

	}elseif($oper_sys == "linux"){
		$command = str_replace("<br/>"," bash {$path_str}/{$FIDDB}.bash \n",$command);
		add_to_cron($command);
	}

	// ??
	$output = shell_exec($command);
	$atLeastOneFetchON = true; // MDF is always on i.e. there is no way to switch it off

	// pass information back so that display will display stop button
	$resB = mysql_query("SELECT value FROM HighLevInfo WHERE name='MDF_status (fet or not)'",$con);
	while($rowB = mysql_fetch_array($resB)){
		$MDF_status_value = trim($rowB[0]);
	}

	if($MDF_status_value == "" || $MDF_status_value == NULL || $MDF_status_value == "not"){
		mysql_query("UPDATE HighLevInfo SET value='fet' WHERE name='MDF_status (fet or not)'",$con);
	}
} // end while for every MDF fetcher

// Both MDF and normal DID done so display message and exit
if($atLeastOneFetchON){
	$started = $_POST[started];
	echo("<form action='RightTop.php?started={$started}' method='post'>Data fetch has started<button type='submit'>OK</button></form>");
}else{
	echo("<form action='RightTop.php?started={$started}' method='post'>No dynamic entities are switched green or fetch information is missing <button type='submit'>OK</button></form>");
}
exit;

end_fiddb:
$res = mysql_query("SELECT fetcher_id FROM Fetcher WHERE SUBSTRING(name,1,3) = 'MDF'",$con);
while($row = mysql_fetch_array($res)){
	$fetcher_id = $row[0];
	$FIDDB = $fetcher_id . "MDF" . $dbase;

	if($oper_sys == "windows"){
		shell_exec("schtasks.exe /delete /f /tn {$FIDDB}");
		if(file_exists($FIDDB.".bat"))unlink($FIDDB.".bat");
		if(file_exists($FIDDB.".vbs"))unlink($FIDDB.".vbs");
	}elseif($oper_sys == "linux"){
		rm_from_cron($FIDDB.".bash");
		unlink($FIDDB.".bash");
	}
	if(file_exists($FIDDB.".args"))unlink($FIDDB.".args");
	if(file_exists($FIDDB))unlink($FIDDB);
	if(file_exists($FIDDB.".lock"))unlink($FIDDB.".lock");
	if(file_exists($FIDDB.".sql"))unlink($FIDDB.".sql");
}
mysql_query("UPDATE HighLevInfo SET value='not' WHERE name = 'MDF_status (fet or not)'",$con);
mysql_close($con);
exit;
// Function to return mysql timestamp in format expected by different switches in tasksch.exe
/* The windows scheduler works as follows
/sc minute  /mo x = run every x minutes starting from current time rounded to next minute + x minutes
/sc hourly  /mo x = run every x hours   starting from current time rounded to next minute + x hours
/sc daily   /mo x = run every x days    starting from current time rounded to next minute + x days
/sc weekly  /mo x = run every x weeks   starting from current time rounded to next minute + x weeks
/sc monthly /mo x = run in month number x starting from current time rounded to next minute on first day of month
/sc monthly /mo 1 = run every month starting from current time rounded to next minute on first day of month
		if x < current month number on server then run every month
		elseif x = current month number run in month number x + current month (what happens if this sum > 12 ??)
		elseif x> current month number run in month number x
		Due to this complication the only modifier /mo allowed with monthly is * (all months)
*/
// Information for following switches is returned
// /SD switch which is mm/dd/yyyy
// /ST switch which is HH:mm
// /MO modifier which hours, minutes etc.
function GetTaskSchedulerFormat($mode,$PD,$units,$time_value,$TZone){

	// Get time value as number of seconds from epoch
	date_default_timezone_set($TZone);
	$time_value = strtotime($time_value);

	// time_value could be starttime and stoptime as recorded in Frequency table
	// these values may not be set. For null values set start to now and stop is currently not supported
	if(!is_int($time_value))$time_value = time();

	/* modify start time using following logic
	If start datetime is specified in frequency then that overrides all
	Minute: if x < 5 then just start from current time rounded to next minute
			elseif 5<= x < 10  round start time to next multiple of 5 minutes
			elseif 10<= x < 15 round start time to next multiple of 10 minutes
			elseif 15<= x < 30 round start time to next multiple of 15 minutes
			elseif 30<= x < 60 round start time to next multiple of 30 minutes
	Hourly: round start time to next full hour
	Daily: round start time to next full hour on day (i.e. midnight of current day)
	Weekly: ask for day and start time on which to run default to monday and next full hour of that day using /D switch and /ST switch  (/ST 00:00:00)
	Monthly: ask for day and start time defaults to first day of every month at next full hour using /ST switch (/ST 00:00:00) and /SD switch (PHP works out first date on which to run)
			 disallow day of month in excess of 28 to allow for irregular size of months
	*/
	$day_of_week = "SAT"; // hardcoded for now
	$day_of_month = 1; // hardcoded for now

	if($PD == "Minute"){
		$modifier = "MINUTE";
		$nearest_sec = 1;
		if($units < 5){
			$nearest_sec = 60;
		}elseif($units < 10){
			$nearest_sec = 300;
		}elseif($units < 15){
			$nearest_sec = 600;
		}elseif($units < 30){
			$nearest_sec = 900;
		}elseif($units < 60){
			$nearest_sec = 1800;
		}
		$time_value = ceil($time_value / $nearest_sec) * $nearest_sec;
	}elseif($PD == "Hour"){
		$modifier = "HOURLY";
		$time_value = ceil($time_value / 3600) * 3600;
	}elseif($PD == "Day"){
		$modifier = "DAILY";
		$time_value = ceil($time_value / 3600) * 3600;
	}elseif($PD == "Week"){
		$modifier = "WEEKLY";
		$time_value = ceil($time_value / 3600) * 3600;
		$day_of_week = "SAT"; // hardcoded for now
	}elseif($PD == "Month"){
		$modifier = "MONTHLY";
		$time_value = ceil($time_value / 3600) * 3600;
		$day_of_month = 1;
	}

	$year = date('Y',$time_value);
	$mnth = date('m',$time_value);
	$day  = date('d',$time_value);
	$hour = date('H',$time_value);
	$min  = date('i',$time_value);

	if($mode == "time"){	// info for /ST switch HH:mm
		return $hour.":".$min;

	}elseif($mode == "day"){	// info for /SD switch mm/dd/yyyy
		return $mnth."/".$day."/".$year;

	}elseif($mode == "modifier"){
		return $modifier;	// info for /MO

	}elseif($mode == "day_of_week"){
		return $day_of_week;	// info for /D

	}elseif($mode == "day_of_month"){
		return $day_of_month;
	}
}





?>
