<?php

include($_SERVER['DOCUMENT_ROOT'].'/include/historian.php');

session_write_close();
ob_start();

//echo 'Query: '."\r\n";
//print_r($_REQUEST);
//echo "\r\n";

$entityBody = file_get_contents('php://input');
$content = json_decode($entityBody);

//print_r($content);
//echo "\r\n";

$val = ob_get_clean();
/*$ip = isset($_SERVER['HTTP_CLIENT_IP']) 
    ? $_SERVER['HTTP_CLIENT_IP'] 
    : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) 
      ? $_SERVER['HTTP_X_FORWARDED_FOR'] 
      : $_SERVER['REMOTE_ADDR']);
	  
$date = new \DateTime('now');
$dt = $date->format('D M d, Y G:i:s');
	  
$val = $dt.",".$ip."\r\n";*/

//file_put_contents($sitefolder.'/grafanaquery.log',$val,FILE_APPEND);

$stime = @DateTime::createFromFormat ( 'Y-m-d\TH:i:s+', $content->range->from);
$etime = @DateTime::createFromFormat ( 'Y-m-d\TH:i:s+' , $content->range->to);

function FormatChannelName($fmt,$assetname,$pointname,$extension = "")
{
	return trim(str_replace("%M",$extension,str_replace("%P",$pointname,str_replace("%A",$assetname,$fmt))));
}

$contextlist = array();


	global $db;
	$qry = "SELECT name,id FROM profiles ORDER BY id";	
		
	$query = $db->query($qry);
		
	while($row = $query->fetch(PDO::FETCH_ASSOC)) 
	{		
		$contextlist[$row['name']] = $row['id'];
	}	


$contextid = 1;

function findassetbyname($search)
{
	//$search = $s->asset;
	$foundid = -1;
	$mod = "";
	global $db;
	global $installfolder;	
	
	$search = strtolower($search);
	
	//Find the asset - this is probably based on name or ern...
	$identifiers = array();
	include_once($installfolder.'/model/property.php');
	$props = Properties::GetAllProperties();
	foreach($props as $px)
	{
		if ($px->type == "TAG")
		{
			$identifiers[] = $px->id;
		}
		if ($px->type == "ID")
		{
			$identifiers[] = $px->id;
		}
	}
	
	$perfectmatch = false;
	
	if (count($identifiers) > 0)
	{
	
		$qry = "SELECT id,name FROM assets JOIN assetvalues ON (assetvalues.assetid = assets.id) WHERE (assetvalues.value LIKE '%".$search."%')".$mod." AND (propertyid IN (".implode(',',$identifiers).")) ORDER BY name";		
		
		$query = $db->query($qry);
		
		$lastname = "";
		while($row = $query->fetch(PDO::FETCH_ASSOC)) 
		{
			if ($foundid == -1)			
				$foundid = $row['id'];
			
			if (strtolower($row['name']) == strtolower($qry))
			{
				$foundid = $row['id'];
				$perfectmatch = true;
				break;
			}
			//break;
		}
	};
	
	//echo $foundid;
	
	if ($perfectmatch == true)
		return $foundid;
	
	$qry = "SELECT id,name FROM assets WHERE (name = '".$search."')".$mod." ORDER BY name";
	//echo $qry;
	
	$query = $db->query($qry);
	
	$lastname = "";
	while($row = $query->fetch(PDO::FETCH_ASSOC)) 
	{
		if ($foundid == -1)
			$foundid = $row['id'];
		if (strtolower($row['name']) == $search)
		{
			$perfectmatch = true;
			$foundid = $row['id'];
			break;
		}
	}
	
	return $foundid;	
}

function ExtractValue($val, $sub = false)
{	
	$v = FALSE;
	if ($val->type == "MEASUREMENT")
	{
		//print_r($val);
		$v = $val->value['measurement'];
	}
	if ($val->type == "STATUS")
	{
		//print_r($val);
		$v =  $val->value['state'];
		if ($sub == true)
		{
			$allprops = Properties::GetAllProperties();
			foreach($allprops as $ap)
			{
				if ($ap->id == $val->id)
				{
					$mp = $ap->GetValueMap($val->value);
					if (isset($mp[$v]))
					{
						$v = $mp[$v];
					}
				}
			}
		}
	}
	if (($val->type == "ENUM") || ($val->type == "LOOKUP"))
	{
		//print_r($val);
		$v =  $val->value['value'];
		if ($sub == true)
		{
			$allprops = Properties::GetAllProperties();
			foreach($allprops as $ap)
			{
				if ($ap->id == $val->id)
				{
					$mp = $ap->GetValueMap($val->value);
					if (isset($mp[$v]))
					{
						$v = $mp[$v];
					}
				}
			}
		}
	}
	if($v === FALSE) return null;
	
	if ($v == '^')
	{
		return "null";
	}
	return $v;	
}

function CleanValue($a)
{
	if (!is_numeric($a))
	{
		if ($a == "^")
		{
			return "null";
		}
		else
		{
			if ($a != "null")
				return '"'.$a.'"';
		}
	}
	if (strlen($a) > 1)
	{
		if ($a[0] == "0")
		{
			return '"'.$a.'"';
		}
	}
	if ($a == "") $a = "null";
	return $a;
}

header('Content-Type: application/json');

ob_start();

$first = true;
?>
[ <?php
	foreach($content->targets as $targ)
	{ 
		if (!isset($targ->asset)) continue;
		if (!isset($targ->property)) continue;
		
		$propname = $targ->property;
		
		$bits = explode(' - ',$propname);
		if (count($bits) > 1)
		{
			$propname = $bits[1].' '.$bits[0];
		}
				
		$firstdp = true;
				
		$assetname = strtolower($targ->asset);
		$propertyname = strtolower($targ->property);
		$nameformat = "%A %P%M";
		if (isset($targ->name))
		{
			if ($targ->name != "")
			{
				$nameformat = $targ->name;
			}
			if ($targ->name == '-')
			{
				$nameformat = "";
			}
		}
		
		$function = strtolower($targ->type);
		
		if ($function == "query")
		{
			if ($first == true)
				$first = false;
			else
				echo ','; 			
			include('aqlquery.php');
			$first = false;
			continue;
		}
		
		if ($function == "table")
		{
			if ($first == true)
				$first = false;
			else
				echo ','; 
			include('generatetable.php');
			$first = false;
			continue;
		}		
		
		if ($function == "profile")
		{
			if ($first == true)
				$first = false;
			else
				echo ','; 
			include('generateprofile.php');
			$first = false;
			continue;
		}		
				
		if ($propertyname == "all analog")
		{			
			//echo 'Bingo!';
			include('allproperties.php');
			$first = false;
			continue;
		}
		
		if ($propertyname == "all discrete")
		{			
			//echo 'Bingo!';
			include('allproperties.php');
			$first = false;
			continue;
		}
		
		$contextid = 1;
		if(property_exists($targ,'context'))
		{
			//echo 'Context: '.$targ;
			if ($targ->context != "Actual")
			{
				
				if (isset($contextlist[$targ->context]))
				{
					$contextid = $contextlist[$targ->context];
				}
				else
				{
					$contextid = 2;
				}
			}
			
		}
		
		if (($function == "point") || ($function == "raw history"))
		{			
			if ($first == true)
				$first = false;
			else
				echo ','; 
	?>	{		
		"target":"<?php echo FormatChannelName($nameformat,$targ->asset,$propname); 
		if ($contextid != 1) echo ' ( '.$targ->context.' )';?>",
		"datapoints":[ <?php
			//Grab history for this property.
			$id = findassetbyname($assetname);
			if ($id <= 0)
			{		
				//echo "No Asset";
				echo "] }\r\n";		
				continue;
			}
			
			//echo 'Asset: '.$id;
			
			$ass = new Asset($id);
			$props = $ass->GetProperties();
			$foundprop = 0;
			
			$readlist = array();
			
			#echo 'Found!';
			
			foreach($props as $p)
			{
				if (strtolower($p->name) == $propertyname)
				{
					$foundprop = $p->id;
					break;
				}
			}
			
			
			if ($foundprop == 0)
			{
				foreach($props as $p)
				{
					$parts = explode(' - ',$p->name);
					if (count($parts) > 1)
					{
						$newname = strtolower($parts[1].' '.$parts[0]);
						if ($newname == $propertyname)
						{
							$foundprop = $p->id;
							break;
						}
					}				
				}
			}
			
			
		    if ($foundprop == 0)
			{	
				$foundalert = 0;
				$propertyname = str_replace("alert: ","",$propertyname);
				$al = $ass->GetAlerts();
				//echo 'Alerts For '.$ass->id;
				//print_r($al);
				foreach($al as $n)
				{
					if (strtolower($n['name']) == $propertyname)
					{
						//echo 'Ding!';
						$foundalert = $n['id'];
						//echo 'Ding '.$foundalert;
					}
				}
				
				if ($foundalert == 0)
				{
					echo "] }\r\n";		
					continue;
				}
			}
			
			if ($foundprop != 0)
			{
				$data = $ass->GetProperties();
				foreach($data as $d)
				{
					if ($d->id == $foundprop)
					{
						$readlist[] = $d;
						break;
					}
				}
				
				$ass->GetValues($readlist,TRUE);
				
				$node = "";
				//print_r($readlist[0]);
				if ((isset($readlist[0]->value['_dynamics'])) && ($readlist[0]->value['_dynamics'][0] == 'measurement'))
				{
					$node = "measurement";
				}
				if ((isset($readlist[0]->value['_dynamics'])) && ($readlist[0]->value['_dynamics'][0] == 'state'))
				{
					$node = "state";
				}
				if ((isset($readlist[0]->value['_dynamics'])) && ($readlist[0]->value['_dynamics'][0] == 'value'))
				{
					$node = "value";
				}
			}
			else
			{
				//print("Setting Node: ".$foundalert);
				$node = $foundalert;
			}
			
			if ($node == "")
			{
				//echo 'Node?';
				echo "] }\r\n";		
				continue;
			}
			
			if ($foundprop != 0) {
				$sourceasset = $readlist[0]->origin;
				if ($readlist[0]->origintype == 'template')
				{
					$sourceasset = $id;
				}
				
				$measurement = $readlist[0]->id;
				
				$pointset = array();
				$v = array();			
				$v['node'] = $node;
				$v['property'] = $measurement;
				$v['asset'] = $sourceasset;
				$v['id'] = 1;
				$pointset[] = $v;
			}
			else
			{
				
				$pointset = array();
				$v = array();			
				$v['node'] = $foundalert;
				$v['property'] = -1;
				$v['asset'] = $id;
				$v['id'] = 1;
				$pointset[] = $v;
				
				//print_r($pointset);
			}
			
			$grain = -1000;
			
			$diff = $etime->getTimestamp() - $stime->getTimestamp() ;
			if ($diff < 1000)
			{
				$grain = -$diff;
			}
						
			$start = gmdate('Y-m-d H:i:s', $stime->getTimestamp());
			$end = gmdate('Y-m-d H:i:s', $etime->getTimestamp());
			
			//print_r($pointset);
			//print_r($start);
			
			$fn = 'interp';
			if ($function == "raw history") 
			{
				$fn = 'raw';
				$grain = -200;
			}
			$res = GetBulkHistory($pointset,$start,$end,$grain,$fn,true,$contextid);		
			if ($res === FALSE)
			{		
				//echo 'No Data!';
				$res = array();
			}
			
			//echo "Results: ";
			//print_r($res);
			
			//print_r($res);
			
			$points = array();
			foreach($res as $r)
			{				
				$p = array();
				$dt = DateTime::createFromFormat('Y-m-d H:i:s',$r[1]);
				if ($dt !== FALSE)
				{
					$p[0] = $dt->getTimestamp();
					$p[1] = $r[2];		
					if ($p[1] == "^") $p[1] = "null";
					if ($p[1] == "None") $p[1] = "null";
					$points[] = $p;
				}
				else
				{
					$dt = DateTime::createFromFormat('Y-m-d H:i:s.u',$r[1]);
					if ($dt !== FALSE)
					{
						$p[0] = $dt->getTimestamp();
						$p[1] = $r[2];		
						if ($p[1] == "^") $p[1] = "null";
						if ($p[1] == "None") $p[1] = "null";
						$points[] = $p;
					}
					//echo 'Bad Timestamp: '.$r[1];
					//exit();
					//file_put_contents($siteroot.'/grafanaerror.log',"Unable To Parse Timestamp: ".$r[1],FILE_APPEND);
				}
			}
			
			$firstdp = true;
			
			foreach($points as $px)
			{
				if ($firstdp == true)
				{
					$firstdp = false;
					echo "\r\n";
				}
				else
					echo ",\r\n";
				
				echo '      ['.$px[1].','.($px[0] * 1000).']';
			}
			?>			
		]
	}
	<?php
		}
		
		if ($function == "current point")
		{	
			if ($first == true)
				$first = false;
			else
				echo ','; 
	
	?>	{
		"target":"<?php echo FormatChannelName($nameformat,$targ->asset,$propname); ?>",
		"datapoints":[ <?php
			//Grab history for this property.
			$id = findassetbyname($assetname);
			if ($id <= 0)
			{				
				echo "] }\r\n";		
				continue;
			}
			
			$ass = new Asset($id);
			$props = $ass->GetProperties();
			$foundprop = 0;
			
			$readlist = array();
			
			
			foreach($props as $p)
			{
				if (strtolower($p->name) == $propertyname)
				{
					$foundprop = $p->id;
					break;
				}
			}
			
			
			if ($foundprop == 0)
			{
				foreach($props as $p)
				{
					$parts = explode(' - ',$p->name);
					if (count($parts) > 1)
					{
						$newname = strtolower($parts[1].' '.$parts[0]);
						if ($newname == $propertyname)
						{
							$foundprop = $p->id;								
							break;
						}
					}				
				}
			}
			
			
		    if ($foundprop == 0)
			{	
				$foundalert = 0;
				$alertvalue = 0;
				$propertyname = str_replace("alert: ","",$propertyname);
				$al = $ass->GetAlerts();
				
				//print_r($al);
								
				foreach($al as $n)
				{					
					if (strtolower($n['name']) == $propertyname)
					{						
						//print_r($n);
						$foundalert = $n['id'];
						$alertvalue = $n['state'];
					}
				}
				
				if ($foundalert == 0)
				{
					echo "] }\r\n";		
					continue;
				}			    
			}
			
			if ($foundprop != 0)
			{
				$data = $ass->GetProperties();
				foreach($data as $d)
				{
					if ($d->id == $foundprop)
					{
						$readlist[] = $d;
						break;
					}
				}
				
				$ass->GetValues($readlist);
				
				$points = array();
				$p = array();
				$p[0] = $stime->getTimestamp();
				$p[1] = ExtractValue($readlist[0]);		
				$points[] = $p;
				$p = array();
				$p[0] = $etime->getTimestamp();
				$p[1] = $points[0][1];	
				$points[] = $p;	
			}
			else
			{
				
				$points = array();
				$p = array();
				$p[0] = $stime->getTimestamp();
				$p[1] = $alertvalue;		
				$points[] = $p;
				$p = array();
				$p[0] = $etime->getTimestamp();
				$p[1] = $alertvalue;	
				$points[] = $p;	
			}					
			
			$firstdp = true;
			
			foreach($points as $px)
			{
				if ($firstdp == true)
				{
					$firstdp = false;
					echo "\r\n";
				}
				else
					echo ",\r\n";
				
				if (!is_numeric($px[1]))
				{
					if (($px[1] == "^") || ($px[1] == "None"))
						$px[1] = "null";
					else
						$px[1] = '"'.$px[1].'"';
				}
				
				echo '      ['.$px[1].','.($px[0] * 1000).']';
			}
			?>			
		]
	}
	<?php
		}
		
		
	}
?> 
]<?php

$astable = false;

$content= ob_get_clean();
echo $content;

?>