<?php
/** 
*   @file WebServer.php
*   @brief  Web services AMDA
*/

class WebServer
{
	private $isSoap = false;
	private $userID, $userPWD = null, $sessionID = null, $IPclient;
	private $dataFileName;
	private $requestManager = null;
	private $paramLoader = null;
	private $service;
	private $requestTime;
	
	function __construct() 
	{
		if (!is_dir(WSConfigClass::getWsResultDir())) mkdir(WSConfigClass::getWsResultDir(), 0775);
	}

	protected function init($data = NULL) 
	{
		$this->requestTime = date('Ymd',time());
		
		if (!isset($data)) {
			$this->userID  = WSConfigClass::getAnonymousUserName();
			return array('success' => true);
		}
		
		if(is_object($data)){
			$vars = get_object_vars($data);
			$this->isSoap = true; 
		}
		else {
			$vars = $data;
		}

		if (isset($vars['userID'])){
			$this->userID  = $vars['userID'];
			IHMConfigClass::setUserName($this->userID);
		}
		else {
			$this->userID  = WSConfigClass::getAnonymousUserName();
		}
		
		$this->sessionID = $this->userID;
		
		if (isset($vars['password']))
			$this->userPWD = $vars['password'];
		else 
			$this->userPWD = WSConfigClass::getAnonymousUserPwd();
		
		return array('success' => true, 'vars' => $vars);
	}
	
	private function initUserMgr($setPathOnly = false) 
	{
		$wsUserMgr = new WSUserMgr();
		$wsUserMgr->initWS($this->userID, $this->userPWD, $this->sessionID,  $setPathOnly, $this->isSoap);
		
		$this->IPclient = $wsUserMgr->getIPClient();
		
		return array('success' => true);
	}
	
	private function throwError($errorType, $msg)
	{
		if ($this->isSoap) 
			throw new SoapFault($errorType, $msg); 
		else 
			exit(json_encode(array("error" => $msg)));
	}
	
	private function isGetPlotRequest($name){

		return (substr($name,0,7) == 'getplot');
	}
	
	private function xsl2vot($inputName, $outputName) 
	{   
		// Load Time table
		$xml = new DomDocument("1.0");
		if (!@$xml->load($inputName))
			$this->throwError("wokrspaceError", "Cannot load time table $inputName for ".$this->userID);

		// Load XSL file
		$xsl = new DomDocument("1.0");
		if (!@$xsl->load(WSConfigClass::getXslDir()."xml2vot.xsl"))
			$this->throwError("systemError", "Cannot load xsl file");
	
		// Import XSL and write output file in vot format
		$xslt = new XSLTProcessor();
		$xslt->importStylesheet($xsl);
		$vot = new DomDocument("1.0");
		if (!@$vot->loadXML($xslt->transformToXML($xml)))
				$this->throwError("systemError", "Cannot convert time table to VOtable");
		
		if (!$vot->save(WSConfigClass::getWsResultDir().$outputName))
			$this->throwError("systemError", "Cannot save time table to result dir");
	}

	private function getDatasetInfo($id)
	{
		$dataSetXml = WSConfigClass::getDataSetInfoDir().$id.".xml";
      
		if (!file_exists($dataSetXml))
			$this->throwError("systemError", "Cannot find info file for dataset ".$id); 
			
		$dataSetDom = new DomDocument("1.0");
		
		if (!@$dataSetDom->load($dataSetXml))
			$this->throwError("systemError", "Cannot load info file for dataset ".$id); 
			
		return $dataSetDom;
	}
	
/*
*  get user TimeTables list; Shared for anonymous user ('impex')
*/
	private function getTimeTablesCatalogsList($object) 
	{
		$this->initUserMgr();
		$dom = new DOMDocument("1.0");
		
		if ($this->userID == WSConfigClass::getAnonymousUserName()) {
			$sharedObjMgr = new SharedObjectsMgr();
			if (!@$dom->load($sharedObjMgr->getTreeFilePath()))
					$this->throwError("workspaceError", "Workspace Error : Cannot load Shared TimeTable list");
                        $tagName = $object == "timetables" ? "timeTableList" : "catalogList";
		}
		else {
				if (!@$dom->load(USERWSDIR.'Tt.xml'))
					$this->throwError("workspaceError", "Workspace Error : Cannot load TimeTable list for ".$this->userID);
                        $tagName = $object == "timetables" ? "timetabList" : "catalogList";
		}
    
		$timetabNode = $dom->getElementsByTagName($tagName);

		if ($timetabNode->length < 1){
				$this->throwError("workspaceWarning", "Workspace Warning : No $object");
		}
		
		$outDOM = new DOMDocument("1.0");
		$outDOM->formatOutput = TRUE;
		$outDOM->preserveWhiteSpace = FALSE;
    
		$newNode = $outDOM->importNode($timetabNode->item(0),TRUE);
		$outDOM->appendChild($newNode);
		
		$ttListResult = $object.'_'.$this->userID.'_'.$this->requestTime.'.xml';
		
		if (!$outDOM->save(WSConfigClass::getWsResultDir().$ttListResult))
			$this->throwError("workspaceError", "Workspace Error : problem while saving $object list file");

		return WSConfigClass::getUrl().$ttListResult;
	}

/*
*  Get corresponding orbit parameter ID
*/
	private function getOrbitParameter($orbitRequest) 
	{
		if (!file_exists(WSConfigClass::getOrbitsXml()))
			$this->throwError('systemError', "No AMDA system orbits file");
			
		$orbitsXml = new DomDocument();

		if (!@$orbitsXml->load(WSConfigClass::getOrbitsXml()))
			$this->throwError('systemError', "Cannot load AMDA system orbits file");
			
		$spacecraft = strtolower($orbitRequest['spacecraft']);
		$spacecraft = str_replace('-', '', $spacecraft);
		
		$xpath = new DOMXpath($orbitsXml);
		$path = '//orbites[@mission="'.$spacecraft.'" and @coordinate_system="'.$orbitRequest['coordinateSystem'].'" and @units="'.$orbitRequest['units'].'" ] ';

		$orbits = $xpath->query($path);
		
		foreach ($orbits as $orbit)
		{
			$datasetID = strtr($orbit->getAttribute('dataset'),"_","-");
			$dataSetDom = $this->getDatasetInfo($datasetID); 
  
			$paramStart = strtotime($dataSetDom->getElementsByTagName('global_start')->item(0)->nodeValue);
			$paramStop =  strtotime($dataSetDom->getElementsByTagName('global_stop')->item(0)->nodeValue);

			if(($paramStart <= strtotime($orbitRequest['startTime']) && (strtotime($orbitRequest['stopTime'])) <= $paramStop)) { 

				return array('success' => true, 
								 'parameterID' => $orbit->getAttribute('xml:id')   
				);
			}
		}
		
		$this->throwError('systemError', 
		"Cannot find orbit data for ".$orbitRequest['spacecraft']." for ".$orbitRequest['startTime']."-".$orbitRequest['stopTime']." in ".$orbitRequest['units']."  ".$orbitRequest['coordinateSystem']."($paramStart  - $paramStop)");
	}
	
	private function doDownloadRequest($interval, $paramList, $formatInfo, $file_info) 
	{
		if (!isset($this->paramLoader))
			$this->paramLoader = new IHMUserParamLoaderClass();

		//Build parameter list
		$params = array();
		
		//TODO template arguments to implement ?
		foreach ($paramList['params'] as $paramId)
		{
			$param = new stdClass;
			
			if (preg_match("#^ws_#",$paramId))
			{
				$res = $this->paramLoader->getDerivedParameterNameFromId($paramId);
				
				if (!$res["success"]) {
					$this->throwError("serverError", "Not available derived parameter $paramId");
				}
				$param->paramid = "ws_".$res['name'];
			}
			else if (preg_match("#^wsd_#",$paramId))
			{
				$res = $this->paramLoader->getUploadedParameterNameFromId($paramId);
				
				if (!$res["success"]){
					$this->throwError("serverError", "Not available parameter $paramId");
				}
				$param->paramid = "wsd_".$res['name'];
			}
			else {
				$param->paramid = $paramId;
			}
			$params[] = $param;
		}

		$ref_sampling_param = isset($interval['ref_sampling_param']) ? $interval['ref_sampling_param'] : NULL;

		$obj = (object)array(
						"sampling" => $interval['sampling'],
						"startDate" => $interval['startTime'],
						"stopDate" => $interval['stopTime'],
						"list" => $params,
						"fileformat" => $formatInfo['format'],
						"timeformat" => $formatInfo['timeFormat'],
						"compression" => $formatInfo['gzip'],
						"ref_sampling_param" => $ref_sampling_param,
						"file_info" => $file_info,
			);	


		if (!isset($this->requestManager))
			$this->requestManager = new RequestManagerClass();
		 
		try {
			$downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $obj);
		} catch (Exception $e) {
			$this->throwError("executionError", "Exception detected : ".$e->getMessage()); 
		}

			
		if (!$downloadResult['success']) {
			$this->throwError("serverError", $downloadResult['message']);
		}
		
		if($downloadResult['status'] == 'in_progress') {
			return ['success' => true, 'status' => 'in progress', 'id' => $downloadResult['id']];
		} elseif ($downloadResult['status'] == 'done') 
		{
			$this->deleteProcess($downloadResult['id']);
			return array('success' => true, 'status' => 'done', 'dataFileURLs' => WSConfigClass::getUrl().$downloadResult['result'], 'exectime' => $downloadResult['exectime']);
		} else {
			return ['success' => false, 'message' => 'Unknown status ' . $downloadResult['status']];
		} 
	}
	
/*
*         delete process after execution : 
*         delete temporary files/folders ( JOBS/process_xxxx, RES/DDxxx ); 
*         delete job node in processManager.xml
*/
	private function deleteProcess($id)
	{
		$obj = (object)array('id' => $id);
   
		if (!isset($this->requestManager))
			$this->requestManager = new RequestManagerClass();

		try {
			$downloadResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PROCESSDELETE, null, $obj);
		} catch (Exception $e) {
			$this->throwError("deleteProcessError", $e->getMessage());
		}
	}
	
	private function excludePrivateNodes($locParamSrc, $locParamDst)
	{
		$locParamSrcDom = new DomDocument("1.0");
		$locParamSrcDom->preserveWhiteSpace = FALSE; /// Important !!! otherwise removeChild() leaves empty text nodes
		
		if (!@$locParamSrcDom->load($locParamSrc))
			$this->throwError("getObsDataTree", "Cannot load  Amda Local DataBase Parameters description file".$this->userID);
 
		$xp =  new domxpath($locParamSrcDom);
		$restricted = $xp->query("//*[@group]");

		foreach ($restricted as $node) {
				$parentNode = $node->parentNode;
				$parentNode->removeChild($node);
				
				if (!$parentNode->hasChildNodes()) {
					if ($parentNode->parentNode){
						$parentParentNode = $parentNode->parentNode;  
						$parentParentNode->removeChild($parentNode);
					}
				}
			}
 
		if (!$locParamSrcDom->save(WSConfigClass::getWsResultDir().$locParamDst))
			$this->throwError('workspaceError', 'Cannot save Amda Local DataBase Parameters description file'.$this->userID);   
	}
	
	private function checkInputTime($startTime, $stopTime) 
	{
		if ($stopTime <= $startTime ) 
			$this->throwError("requestError", "Requested time interval should be greater than 0"); 
	}
	
/************************** WEB SERVICES **************************************/	
/*
*   generate AUTH token for access to REST services 
*/
	public function getNewToken()
	{
		// generate token from timeStamp and some salt
		$newToken = md5(1321 * (int)( time() / WSConfigClass::$timeLimitQuery));
		
		return array('success' => true, 'token' => $newToken);
	}
	
/*
*   public data only : anonymous user (impex)
*/
	public function getObsDataTree() 
	{         
		$res = $this->init();	
		$this->initUserMgr();
		
		$locParamSrc = USERWSDIR.'LocalParams.xml'; 
		
		$locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml';

// 		if (!copy($locParamSrc,WSConfigClass::getWsResultDir().$locParamDst))
// 			$this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file');   

		$this->excludePrivateNodes($locParamSrc,$locParamDst);
		return  array('success' => true,'WorkSpace' => array("LocalDataBaseParameters" => WSConfigClass::getUrl().$locParamDst));
	}

/*
*   get Parameter List for given user
*/
	public function getParameterList($data) 
	{         
		$res = $this->init($data);
		$this->initUserMgr(); 

		$vars = $res['vars'];

		$locParamSrc = USERWSDIR.'LocalParams.xml'; 
		$wsParamSrc =  USERWSDIR.'WsParams.xml';
		
		$locParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_AmdaLocalDataBaseParameters.xml';
		$wsParamDst = substr(strtolower(__FUNCTION__),3).'_'.$this->userID.'_'.$this->requestTime.'_UserDefinedParameters.xml';

// 		if (!copy($locParamSrc, WSConfigClass::getWsResultDir().$locParamDst))
// 			$this->throwError('workspaceError', 'No Amda Local DataBase Parameters description file for '.$this->userID);
		
		$this->excludePrivateNodes($locParamSrc,$locParamDst);
		
		if (($this->userID == WSConfigClass::getAnonymousUserName()) ||  !copy($wsParamSrc, WSConfigClass::getWsResultDir().$wsParamDst))
			return  array('success' => true,'ParameterList' => 
					array("LocalDataBaseParameters" =>  WSConfigClass::getUrl().$locParamDst));

		return  array('success' => true,'ParameterList' => 
					array("UserDefinedParameters" => WSConfigClass::getUrl().$wsParamDst, 
							"LocalDataBaseParameters" =>  WSConfigClass::getUrl().$locParamDst));
	}

/*
*   getParameter 
*/
	public function getParameter($data) 
	{
		$res = $this->init($data);
    
		if (!$res['success']){
			$this->throwError("requestError", "Cannot parse request"); 
		}

		$this->initUserMgr();

		$vars = $res['vars'];

		if (empty($vars["startTime"])) {
			$this->throwError("requestError", "Missing startTime definition");
		}

		if (empty($vars["stopTime"])) {
			$this->throwError("requestError", "Missing stopTime definition");
		}
		
		if (is_numeric($vars["startTime"])) {
			$this->checkInputTime($vars["startTime"],$vars["stopTime"]);
			$vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]);
			$vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]);
		}
		else {
			$this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); 
		}
		
		if (empty($vars["timeFormat"])) {
			$timeFormat = "ISO8601";
		}
		else {
			$timeFormat = $vars["timeFormat"];
		}

		$sampling = !empty($vars["sampling"]) ? $vars["sampling"] : NULL;
		$ref_sampling_param = NULL;
		$file_info = "";

		if (empty($vars["parameterID"])) {
			$this->throwError("requestError", "Missing parameterID definition");
		}
		$paramId = array();
		if (strpos($vars["parameterID"], ',')) {
			$paramId = explode(',', $vars["parameterID"]);

			if (!isset($sampling))
			{
				$ref_sampling_param = trim($paramId[0]);
			}

			foreach ($paramId as &$id) {
				$id = trim($id);
				if (!empty($file_info)) {
					$file_info .= "-";
				}
				$file_info .= $id;
			}
		}
		else {
			array_push($paramId, $vars["parameterID"]);
			$file_info = $vars["parameterID"];
		}

		if (empty($vars["gzip"]))
			$gzip = 0;
		else
			$gzip = ($vars["gzip"] == 1);

		$outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII'; 
			
		$this->service = strtolower(__FUNCTION__);

		$res = $this->doDownloadRequest(
					array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling,
						"ref_sampling_param" => $ref_sampling_param),
					array("params" => $paramId),
					array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $file_info);
 
		if ($res['success']) 
			return $res;
	
		$this->throwError("serverError", $res['message']); 
	}
	
/*
*  get user Catalogs list; Shared for anonymous user (impex)
*/
	public function getCatalogsList($data) 
	{
		$this->init($data);
	
		return array('success' => true, 'CatalogsList' => $this->getTimeTablesCatalogsList('catalogs'));
	}

/*
*  get user TimeTables list; Shared for anonymous user (impex)
*/
	public function getTimeTablesList($data) 
	{
		$this->init($data);
		 
		return array('success' => true, 'TimeTablesList' => $this->getTimeTablesCatalogsList('timetables'));
	}
	
	public function isAlive()
	{ 
		return true;
	}
    
/*
*   get Dataset
*/
	public function getDataset($data) 
	{
		$res = $this->init($data);
		
		if (!$res['success']){
			$this->throwError("requestError", "Cannot parse request"); 
		}
		
		$this->initUserMgr();

		$vars = $res['vars'];
		
		if (is_numeric($vars["startTime"])) {
			$this->checkInputTime($vars["startTime"],$vars["stopTime"]);
			$vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]);
			$vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]);
		}
		else {
			$this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); 
		}
	 
		if (empty($vars["timeFormat"])) {
			$timeFormat = "ISO8601";
		}
		else {
			$timeFormat = $vars["timeFormat"];
		}

		if (empty($vars['datasetID'])) {
			$this->throwError("requestError", "Missing datasetID definition");
		}
		$datasetId = $vars['datasetID'];
		$dataSetDom = $this->getDatasetInfo($datasetId);
		
		$params = $dataSetDom->getElementsByTagName("parameter");
		
		if ($params->length == 0)
			$this->throwError("systemError", "Cannot find parameter list for dataset ".$datasetId); 
      
		$paramId = array();
	  
		foreach ($params as $p)
				$paramId[] =  $p->nodeValue;
 
		if (empty($vars["sampling"]))
		{ 
			$sampling = NULL;
			$ref_sampling_param = $paramId[0];
		}
		else {
			$sampling = $vars["sampling"];
			$ref_sampling_param = NULL;
		}
 
		if (empty($vars["gzip"]))
			$gzip = 0;
		else
			$gzip = ($vars["gzip"] == 1);

		$outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII';

		$this->service = strtolower(__FUNCTION__);

		$res = $this->doDownloadRequest(
					array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling, "ref_sampling_param" => $ref_sampling_param),
					array("params" => $paramId),
					array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $datasetId);
  
		if ($res['success']) return $res;

		$this->throwError("serverError", $res['message']); 
	}
	
/*
*   get status for jobs in batch
*/
	public function getStatus($data) 
	{
		$result = $this->init($data);
		
		$id = $result['vars']['id'];
		
		if (!isset($this->requestManager))
			$this->requestManager = new RequestManagerClass();
			
		try 
		{
			$res = $this->requestManager->runWSRequest('nobody', 'nobody', FunctionTypeEnumClass::PROCESSGETINFO, null, $id);
		} 
		catch (Exception $e) 
		{
			$this->throwError("executionError", "Exception detected : ".$e->getMessage());
		}
		
		if (!$res['success']) {
			$this->throwError("processError","Cannot retrieve process $id info");
		}

		if ($res['status'] == 'in_progress') {
			return array('success' => true, 'status' => 'in progress');
		}
		
		if ($res['error']) {
			$this->throwError("processError","Process $id error code");
		}
		
		$this->deleteProcess($res['id']);
		
		$resultTag = $this->isGetPlotRequest($res['result']) ? 'plotURL' : 'dataFileURLs';
		
		return  array('success' => true, 'status' => $res['status'],  $resultTag => WSConfigClass::getUrl().$res['result']);
	}
	
/*
*    TODO Can be done by TTCONVERT function of AMDA_Kernel - more hard !!!
*    TODO Think about this if merge/union will be also done by AMDA_Kernel
*
*    get Time Table : shared for anonymous user (impex) ; user' for user
*/
	public function getTimeTable($data) 
	{
		$res = $this->init($data);
		
		if (!$res['success']){
			$this->throwError("requestError", "Cannot parse request"); 
		}
		
		$this->initUserMgr();
		
		$ttID = $res['vars']['ttID'];

		if ($this->userID == WSConfigClass::getAnonymousUserName()) {
			$sharedObjMgr = new SharedObjectsMgr();
			$ttSrc = $sharedObjMgr->getDataFilePath('timeTable', $ttID);
		}
		else
			$ttSrc = USERTTDIR.$ttID.'.xml';

		if (!file_exists($ttSrc)) {
			$this->throwError("workspaceError", "No such table ".$ttID." for user ".$this->userID);
		}

		$ttDst = substr(strtolower(__FUNCTION__), 3)."_".$this->userID."_".$this->requestTime."_$ttID.xml"; 

		//TODO can be done by
		// $res = $this->requestManager->runWSRequest($this->userID, $this->IPclient,FunctionTypeEnumClass::TTCONVERT, null, $ttID);
		$this->xsl2vot($ttSrc,$ttDst);

		return array('success' => true, 'ttFileURL' => WSConfigClass::getUrl().$ttDst);
	}

/*
*   get Orbits
*/ 
	public function getOrbites($data) 
	{
		$res = $this->init($data);
		
		if (!$res['success']){
			$this->throwError("requestError", "Cannot parse request"); 
		}
		
		$this->initUserMgr();

		$vars = $res['vars'];
		
		if (is_numeric($vars["startTime"])) {
			$this->checkInputTime($vars["startTime"],$vars["stopTime"]);
			$vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]);
			$vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]);
		}
		else {
			$this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); 
		}
	 
		if (empty($vars["timeFormat"])) {
			$timeFormat = "ISO8601";
		}
		else {
			$timeFormat = $vars["timeFormat"];
		}

		if (empty($vars["spacecraft"])) {
			$this->throwError("requestError", "Missing spacecraft definition");
		}
		$spacecraft = $vars["spacecraft"];

		if (empty($vars["coordinateSystem"])) {
			$this->throwError("requestError", "Missing coordinateSystem definition");
		}
		$coordinateSystem = $vars["coordinateSystem"];

		if (empty($vars["units"]))
			$units = "km";
		else
			$units = $vars["units"];

		$orbitRequest = array("startTime" => $vars["startTime"],
				"stopTime"  => $vars["stopTime"],
				"spacecraft" => $spacecraft,
				"coordinateSystem" => $coordinateSystem,
				"units" => $units
				);
  
		$orbitParam = $this->getOrbitParameter($orbitRequest);
		
		$paramId = array();
		array_push($paramId, $orbitParam['parameterID']);

		if (empty($vars["gzip"]))
			$gzip = 0;
		else
			$gzip = ($vars["gzip"] == 1);

		$sampling = !empty($vars["sampling"]) ? $vars["sampling"] : NULL;

		$outputFormat = !empty($vars["outputFormat"]) ? $vars["outputFormat"] : 'ASCII';
			
		$this->service = strtolower(__FUNCTION__);
      
		$res = $this->doDownloadRequest(
					array("startTime" => $vars["startTime"], "stopTime" => $vars["stopTime"], "sampling" => $sampling),
					array("params" => $paramId),
					array("format" => $outputFormat, "timeFormat"=> $timeFormat, "gzip"=>$gzip), $orbitParam['parameterID']);
 	 
		if ($res['success']) return $res;
 
		$this->throwError("serverError",$res['message']);    
	}

/*
*  getPlot : predefined;  by mission
*/
	public function getPlot($data) 
	{
		$res = $this->init($data);
		
		if (!$res['success']){
			$this->throwError("requestError", "Cannot parse request"); 
		}
		
		$this->initUserMgr();
		
		$vars = $res['vars'];
		$mission = $vars["missionID"];
		
		if (is_numeric($vars["startTime"])) {
			$this->checkInputTime($vars["startTime"],$vars["stopTime"]);
			$vars["startTime"] = date("Y-m-d\TH:i:s", $vars["startTime"]);
			$vars["stopTime"] = date("Y-m-d\TH:i:s", $vars["stopTime"]);
		}
		else {
			$this->checkInputTime(strtotime($vars["startTime"]),strtotime($vars["stopTime"])); 
		}
	 
		$resultFilePrefix = strtolower(__FUNCTION__)."_".$mission."_".date("YmdHms",strtotime($vars["startTime"]))."_".date("YmdHms",strtotime($vars["stopTime"]));
		
		if ($this->userID != WSConfigClass::getAnonymousUserName()) 
			$resultFilePrefix .= "_".$this->userID;

		$dom = new DomDocument("1.0");
		if (!@$dom->load(WSConfigClass::getXslDir()."AmdaPlots.xml"))
			$this->throwError("systemError", "Cannot load predefined plot definition"); ;

		$missionTag = $dom->getElementById($mission);
		$params = $missionTag->getElementsByTagName('param');

		$paramsList = array();
		foreach ($params as $param)
			$paramsList[] = $param->getAttribute('name');

		$requestObject = (Object) array(
			"nodeType" => "request",
			"file-format" => "PNG",
			"result-file" => $resultFilePrefix,
			"timesrc" => "Interval",
			"startDate" => $vars["startTime"],
			"stopDate" => $vars["stopTime"],
			"parameters" => array()
		);
    
		foreach ($paramsList as $paramToPlot)
		{
			$paramObject = (Object) array(
				"paramid" => $paramToPlot
			);
			
			$requestObject->{"parameters"}[] = $paramObject;
		}

		$this->service = strtolower(__FUNCTION__);
		
		if (!isset($this->requestManager))
			$this->requestManager = new RequestManagerClass();
		
		try {
			$plotResult = $this->requestManager->runWSRequest($this->userID, $this->IPclient, FunctionTypeEnumClass::PARAMS, $this->service, $requestObject);
		} catch (Exception $e) {
				$this->throwError("plotError", "Exeption detected : ".$e->getMessage());
		}
		
		if (!$plotResult['success']) {
			$this->throwError("serverError", $plotResult['message']);
		}
		
		if($plotResult['status'] == 'in_progress') {
			return ['success' => true, 'status' => 'in progress', 'id' => $plotResult['id']];
		} elseif ($plotResult['status'] == 'done') 
		{
			$this->deleteProcess($plotResult['id']);
			return array('success' => true, 'status' => 'done', 'plotFileURL' => WSConfigClass::getUrl().$plotResult['result']);
		} else {
			return ['success' => false, 'message' => 'Unknown status ' . $plotResult['status']];
		} 
	}
}
?>