<?php
/**  
*     @class BaseManager
*     @brief Management of user uploaded data files in data base
*     @author Elena
*     @version $Id: BaseManager.php 2914 2015-05-19 10:31:38Z elena $
*    
*/
 
class BaseManager 
{
	public $xp, $xslt;
	public $baseDom; 
	private $fileDomName, $baseDomName;

	function __construct() 
	{  
		define("DELTA", 120);   // minumum file size in secs 
		
		if (getenv('USER_DATA_PATH') != "")
				$this->baseDomName = getenv('USER_DATA_PATH')."base.xml";
		else 
			$this->baseDomName = USERDATADIR."base.xml";

		$this->fileDomName = USERWSDIR."Files.xml";
		
		$this->baseDom =  new DomDocument("1.0");

		if (file_exists($this->baseDomName)) 
					$this->baseDom->load($this->baseDomName);
		else {
			$baseElement = $this->baseDom->createElement("base");
			$this->baseDom->appendChild($baseElement);
		} 

		$this->xp = new domxpath($this->baseDom);    
		$this->xslt = new XSLTProcessor();

		$xsl = new DomDocument("1.0");
		$xsl->load(XMLPATH."base.xsl");
		$this->xslt->importStylesheet($xsl);
	}

/*
*   Provide an unique ID
*/
	public function getNewId() 
	{
		//  Get all ID attributes
		$vis = $this->xp->query("//vi/@id");

		if ($vis->length > 0) {
					$idList = array();
					if($vis->length > 0) for ($i = 0; $i < $vis->length; $i++) 
															$idList[] = $vis->item($i)->nodeValue;                 
					sort($idList);

					for ($i = 0; $i < count($idList); $i++) {
						if ($idList[$i] > $i) { 
										$newID = $i;
										break;
							}  
							$newID = $i+1;  
						}                 
			} else
				$newID = 0; 

		return $newID;
	}
    
   /*
   *  Get filename to create IMPEX parameter if VI exists already
   */
   public function getFirstFileName($viID)
   {
		$vis = $this->xp->query("//vi[@id = '".$viID."']");
		if ($vis->length > 0) 
			$vi = $vis->item(0);
		else
			throw new Exception('No VI '.$viID);
			
		$files = $vi->getElementsByTagName('file');
		if ($files->length > 0) 
			return $files->item(0)->getAttribute('name');
			
		throw new Exception('Empty VI '.$viID);  
   }
   
   
	public function fileMask($fileName, $maskName) 
	{
		$mask = explode("*", $maskName);
		
		for ($i = 0; $i < count($mask); $i++)  
			if ($mask[$i] != null)
				if (strpos($fileName, $mask[$i]) === false) return false;
				
		return true;
	}

	/*
	*   New file is uploaded -> check if it should be added into MASK 
	*/
	public function addFile($fileName, $start = null, $stop = null) 
	{
	  
	  // standard file upload : start / stop get from file
		if (!$start)
		{
			$fileDom = new DomDocument("1.0");
			$fileDom->load($this->fileDomName);       
			$file = $fileDom->getElementById($fileName);
			$start = $file->getAttribute('start');
			$stop = $file->getAttribute('stop');			
		}
		
		$lastMask = null; 
		
		$masks = $this->baseDom->getElementsByTagName("mask");

		if ($masks->length > 0) 
		{
			foreach ($masks as $mask)                       
				if ($this->fileMask($fileName, $mask->nodeValue)) 
				{
					$lastMask = $mask->nodeValue;

					$newFile = $this->baseDom->createElement("file");              
					$newFile->setAttribute('name', $fileName);			
					
					$newFile->setAttribute('start', $start);
					$newFile->setAttribute('stop', $stop);

					$vi = $mask->parentNode;
					$vi->appendChild($newFile);

					$vi_start = $vi->getAttribute('start');
					if (!$vi_start || $vi_start > $start) 
						$vi->setAttribute('start',$start);
						
					$vi_stop = $vi->getAttribute('stop');
					if (!$vi_stop || $vi_stop < $stop) 
						$vi->setAttribute('stop',$stop);                          
				} 
		} 
		// sort by time
		$this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName);
									
		return $lastMask;           
	}
	
/*
*        File was deleted
*/
	public function delFile($fileObj) 
	{                            
		$start = $fileObj->getAttribute($start);
		$stop = $fileObj->getAttribute($stop);
		$vi =  $fileObj->parentNode;                                                                                   
		$vi->removeChild($fileObj);
		$mask = $vi->getElementsByTagName("mask")->item(0)->nodeValue;
		$length = $vi->getElementsByTagName("file")->length;

		if ($length == 0) 
		{               
			$this->baseDom->getElementsByTagName("base")->item(0)->removeChild($vi);
		}  
		else  
		{                           
			$vi->setAttribute('start', $this->updateStart($vi));            
			$vi->setAttribute('stop',$this->updateStop($vi)); 
		} 

		$this->baseDom->save($this->baseDomName); 

		return array('mask' => $mask, 'length' => $length);
	}

	/*
	*
	*/      
	public function updateStart($vi) 
	{        
		$files = $vi->getElementsByTagName("file");
		if ($files->length == 0) return "EMPTY";

		$starts = Array();
		foreach ($files as $file) 
			$starts[] =  $file->getAttribute("start");

		return  min($starts);
	}

/*
*
*/   
	public function updateStop($vi) 
	{    
		$files = $vi->getElementsByTagName("file");
		if ($files->length == 0) return "EMPTY";

		$stops = Array();
		foreach ($files as $file) 
					$stops[] =  $file->getAttribute("stop");

		return  max($stops);
	}
     
/*
*     New mask was added  
*/
    public function appendFiles($newVi, $fileMask) 
    {
        $fileDom = new DomDocument("1.0");
        $fileDom->load($this->fileDomName);
        $files = $fileDom->getElementsByTagName("file");

        if ($files->length > 0) 
        {
            $starts = Array();
            $stops = Array();

            foreach ($files as $file) 
            {
                $fileName = $file->getAttribute("name"); 
                if ($this->fileMask($fileName, $fileMask)) 
                {
                    $newFile = $this->baseDom->createElement("file");              
                    $newFile->setAttribute('name', $fileName);
                    $start = $file->getAttribute("start");
                    $stop = $file->getAttribute("stop");
                    $newFile->setAttribute('start', $start);
                    $newFile->setAttribute('stop', $stop);
                    $newVi->appendChild($newFile);
                    $starts[] = $start;
                    $stops[] = $stop;
                } 
            } 

           $newVi->setAttribute("start", min($starts));
           $newVi->setAttribute("stop", max($stops));
        }                          
      }

/*
*       
*/
	public function getOldMask($fileMask) 
	{               
		$masks = $this->baseDom->getElementsByTagName("mask");
		
		if ($masks->length > 0) 
		{
			foreach ($masks as $mask) {
					// mask exists  
					if (strcmp($mask->nodeValue, $fileMask) == 0) return null;                            
					
					if (strncmp($mask->nodeValue, $fileMask, 5) == 0) 
					{                               
						// less common
						if (strlen($mask->nodeValue) <= strlen($fileMask)) return null;
						// more common - delete old, create new                                                               
						return $mask->nodeValue;                                                                                                                       
					} 
			}
		}
		return null;
	}
/*
*       
*/
	public function addVI($fileMask, $format) 
	{                                                             
		$newVi = $this->baseDom->createElement("vi");
		$newId = $this->getNewId();
		$newVi->setAttribute('id', $newId);
		
		if ($format == 'txt') $format = 'ascii';
		
		$newVi->setAttribute('format', strtoupper($format));
		$newVi->appendChild($this->baseDom->createElement("mask",$fileMask)); 
		$this->appendFiles($newVi, $fileMask);
		
		$this->baseDom->documentElement->appendChild($newVi);
		
		 /* SORT files by Start Time */         
		$this->xslt->transformToDoc($this->baseDom)->save($this->baseDomName); 
		return $newId;            
	}
 
	public function delVI($fileMask) 
	{          
		$vi = $this->xp->query("//vi[mask='".$fileMask."']");

		if ($vi->length > 0) 
					$vi->item(0)->parentNode->removeChild($vi->item(0));

		$this->baseDom->save($this->baseDomName); 
	} 

	public function getVI($fileMask) 
	{
		$vi = $this->xp->query("//vi[mask='".$fileMask."']");

		if ($vi->length > 0) 
						return $vi->item(0)->getAttribute("id");

		return -1;
	}
     
	public function existsVi($mask)
	{
		$vi = $this->xp->query("//vi[mask='".$mask."']");
		if ($vi->length > 0) 
						return true;
		else 
						return false;
	}
   
   /*
   * Check intervals to be ordered in the Remote Centers (IMPEX)
   */
	public function intervalsToGet($requestStart, $requestStop, $mask)
	{       
		$vis = $this->xp->query("//vi[mask='".$mask."']");
		if ($vis->length == 0)  return false;

		$vi = $vis->item(0);
		$files = $vi->getElementsByTagName('file'); 

		$start = array();
		$stop = array();
		// otherwise - the case of IPIM - only one file
		if (strpos($mask, "*") > 0)
		{
			$globalStart = (int)$vi->getAttribute("start");
			$globalStop = (int)$vi->getAttribute("stop");

			if ($requestStart > $globalStop  ||  $requestStop < $globalStart)  
			{  
				$start[] = $requestStart; 
				$stop[]  = $requestStop;  
			}                
			else
			{ 
					if ($requestStart < $globalStart - DELTA ) {
								$start[] = $requestStart;
								$stop[] = $globalStart;
				}

				if ($requestStop > $globalStop + DELTA ) {
								$start[] = $globalStop;
								$stop[] = $requestStop;
				} 

				for ($i = 0; $i < $files->length; $i++)      
						if ((int)$files->item($i)->getAttribute("stop") >= $requestStart) break;

				for ($j = $i; $j < $files->length; $j++)  
						if ((int)$files->item($j)->getAttribute("start") >= $requestStop) break;

				$d = $j+1 < $files->length -1  ? $j+1 : $files->length - 1;

				for ($k = $i; $k < $d ; $k++) {
						$stopT = (int)$files->item($k)->getAttribute("stop");
						$startT = (int)$files->item($k+1)->getAttribute("start");
						if ($startT - $stopT > DELTA) {         
							$start[] = $stopT;
							$stop[] = $startT;         
						}
				}
			}
		}
		return array('start' => $start, 'stop' => $stop);
	}
	
   /*
	* Get VI Start - Stop
	*/ 
	public function getStartStop($id) 
	{  
		$this->baseDom->load($this->baseDomName);
		$xpath = new DOMXpath($this->baseDom);
	
		$vis = $xpath->query("//vi[@id=".$id."]");

		if ($vis->length == 0) 
			return "nodata";

		$vi = $vis->item(0);
				
		$start = $vi->getAttribute("start"); 
		$stop = $vi->getAttribute("stop");

		return date("Y-m-d", $start)."T".date("H:i:s", $start)."-".date("Y-m-d", $stop)."T".date("H:i:s", $stop);
	} 
 
	/*
	*  Return VI Description (Start - Stop)
	*/
	public function getViDesc($vi)
	{ 
		return $this->getStartStop($vi);   
	}
	
	/*
	* Delete Vi in base.xml and delete corresponding files in User DATA dir
	*/
    public function deleteViTotal($viId)
	{ 
		$vi = $this->xp->query("//vi[@id=".$viId."]");

		if ($vi->length > 0) {
			$files = $vi->item(0)->getElementsByTagName('file');
			foreach ($files as $file)
			{
			  $fileName = USERDATADIR.$file->getAttribute('name');
			  if (file_exists($fileName)) unlink($fileName);
			}
			
			$vi->item(0)->parentNode->removeChild($vi->item(0));
			$this->baseDom->save($this->baseDomName);		
		} 
	} 
		
}
?>