<?php
/**
 * @class UserWsTransfer
 * @version $Id: UserWsTransfer.php 1718 2013-08-28 15:52:38Z myriam $
 *
 */

 class UserWsTransfer {  

  private $ws, $Mgr;
  private $wsDir;
  private $ws_deleted;
   
  function __construct($user) {  

        define('OLDUSERPATH', ROOT_PATH.'USERS/');
        define('TRANSFERUSER', $user);
        define('CONVERSIONDIR',  BASE_PATH.'utils/conversion/');

        $this->ws = new DomDocument("1.0");
        $this->wsDir = OLDUSERPATH.TRANSFERUSER.'/WS/';

        $this->ws_deleted = array();
   }

 public function checkWS() {

  // old ws        
   if (!is_dir(OLDUSERPATH.TRANSFERUSER)) {
                                error_log('no  '.TRANSFERUSER.' at old AMDA',1,email);
                                return array('success' => false, 'error' => 'Sorry, it seems you have no account at old AMDA');
    }

   if (!file_exists($this->wsDir.'ws.xml')) {
                                error_log('no ws.xml for '.TRANSFERUSER,1,email);
                                return array('success' => false, 'error' => 'Sorry, we failed to find your workspace at old AMDA');
    }

   if (!$this->ws->load($this->wsDir.'ws.xml')) {
                                        error_log('cannot load ws.xml for '.TRANSFERUSER,1,email);
                                        return array('success' => false, 'error' => 'Sorry, we failed to access your workspace at old AMDA');
   }
   
    return array('success' => true);

 }

  public function hasAlias($expression) {
       
       return (strpos($expression, "#") !== false);

  }


  public function replaceAliases($expression){

      $aliasXML = new DomDocument("1.0");
      $aliasXML->load($this->wsDir.'alias.xml'); 
      $aliases_ = $aliasXML->getElementsByTagName('alias');

      if ($aliases_->length == 0) return $expression;

      $aliases = array();
      foreach ($aliases_ as $alias) {
            $aliases["#".$alias->getAttribute("name")] = $alias->nodeValue; 
      }
// sort in desc order by key (alias itself)
      krsort($aliases, SORT_NATURAL);
        
         foreach ($aliases as $alias => $param) {

            if (!$this->hasAlias($expression))
                   break;
            if (strpos($expression, $alias) !== false) {
                 $newExp = str_replace($alias, $param, $expression);
                 $expression = $newExp;
            }
        }
        return $expression;
    }

//duplication of FilesMgr method
 public function getSampling($fileName, $format) {
 
      if ($format === 'cdf') {
            copy($fileName, "temp.cdf");         
            exec('cdfsamplingfromdata ', $result); 
            unlink("temp.cdf");
            $minSamp = $result[count($result)-1]; 
         }
      else if ($format === 'cef') {
            exec('cefsampling '.$fileName, $result); 
            $minSamp = $result[count($result)-1];
       }
       else $minSamp = null;
//TODO if min & max                           
            return $minSamp;

 }
 

 public function deleteParam($exp, $isPlot) {

    $deletedXML = new DomDocument("1.0");

    if ($isPlot) $deletedXML->load(CONVERSIONDIR.'Plot_Deleted.xml'); 
    else $deletedXML->load(CONVERSIONDIR.'Deleted.xml'); 

    $deletedNodes = $deletedXML->getElementsByTagName('deleted');
    $toDelete = false;

   if (strpos($exp, "CDAWEB") !== false) 
                return true;                
   
   
    foreach ($deletedNodes as $item) {
        if (strpos($exp, $item->getAttribute('xml:id')) !== false)  {
        $toDelete = true;
        break;
        }
    }

  return $toDelete;
}

  public function updateParams($expression, $isPlot){
   
 
    $convertXML = new DomDocument("1.0");

    if ($isPlot) $fileNames = glob(CONVERSIONDIR.'*_convertPlot.xml');
    else $fileNames = glob(CONVERSIONDIR.'*_convert.xml');


    foreach ($fileNames as $file) {
       
       if (!$convertXML->load($file)) 
                        error_log('ERROR loading '.$file,1,email);
        $convertedNodes = $convertXML->getElementsByTagName('param_convert');
  
        foreach ($convertedNodes as $item) {   
            $pairs[$item->getAttribute('oldid')] = $item->getAttribute('xml:id');
        }    
        krsort($pairs, SORT_NATURAL);
        $newExp = strtr($expression, $pairs);
        $expression = $newExp;
         
    }
 
    return $expression;
  }

  public function convertArgs($parId, $args){        
 //TODO arguments.php via Ext.Direct call     
        $cmd = 'php '.BASE_PATH.'php/arguments.php "'.$parId.'"';

        $arguments = explode(",", $args);
        $newArgs = array();

        $res = exec($cmd);

//TODO just main arguments....
        foreach ($arguments as $item) {
            if (strpos($item, "/") !== false) 
                                    $arg = substr($item,1,strlen($item));
            switch ($arg) {
                case "black" :
                case "blue" :
                case "green" :
                case "red" :
                              $newArgs[] = "Color=".$arg;
                              break;

                case "gsm" :
                case "sm" : if (strpos($res, $arg) !== false)
                                $newArgs[] = "RefFrame=".strtoupper($arg);
                              break;

                case "log" :
                case "lin" : if (strpos($res, $arg) !== false)
                                $newArgs[] = "Scale=".$arg;
                               break;
                case "cyl" : 
                                $newArgs[] = "OrbitPresentation=".strtoupper($arg);
                                break;
                default :
                            
            } 
        }

        if  (count($arguments) === 0) return  "select...";

        if (count($arguments) > 1)  return implode("&",$newArgs);

        return $newArgs;
    }

  public function createFolders($listName, $nodeType){
  // create folders
        $folders = $this->ws->getElementsByTagName($listName)->item(0)->getElementsByTagName('level1');
        $obj = new stdClass();
        foreach ($folders as $folder) {
            $obj->leaf = false;
            $obj->old_name = "new Folder";
            $obj->name = $folder->getAttribute('name');
            $obj->parent = $nodeType."-treeRootNode";
            $obj->nodeType = $nodeType;

            $this->Mgr->renameObject($obj); 
        }
    }

  public function transferDerived() {

        $msg = '<b>WS (Derived) Params:</b><br/>';
    // derived parameters                
        $this->Mgr = new DerivedParamMgr('derivedParam');
        $this->createFolders('paramList','derivedParam');
   
    // get old params  
        $wsParams = $this->ws->getElementsByTagName('param');
        if ($wsParams->length == 0) {
               return array('success' => true, 'msg' => 'No parameters');
        }
        $obj = new stdClass();
        foreach ($wsParams as $param) {        
            $obj->name = $param->getElementsByTagName('name')->item(0)->nodeValue;
            $expression = $param->getElementsByTagName('buildchain')->item(0)->nodeValue;

            if ($this->hasAlias($expression)) {
                    $newExp = $this->replaceAliases($expression);  
                    $expression = $newExp;
            }
            if ($this->deleteParam($expression)) {
                    $msg .= 'deleted  name:<b>'.$obj->name.'</b>; expression: '.$expression.'<br/>';
                 //   error_log( 'For INFO : DELETED '.$expression,1,email);
                    $this->ws_deleted[] = $obj->name;
                    continue;
            }
           
            $obj->buildchain = $this->updateParams($expression);
            $obj->timestep = $param->getElementsByTagName('timestep')->item(0)->nodeValue;
            $obj->units = $param->getElementsByTagName('units')->item(0)->nodeValue;
            $obj->description = $param->getElementsByTagName('description')->item(0)->nodeValue;
            $obj->ytitle = ""; 
            $obj->nodeType = "derivedParam";
            $obj->leaf = true;

            $this->Mgr->objectDom = new DomDocument("1.0");
            if ($param->parentNode->tagName === 'level1') {
                $folder_id = $param->parentNode->getAttribute('id');
                $this->Mgr->createObject($obj, $folder_id);
            }
            else {
                $this->Mgr->createObject($obj);
            }
        }
        $msg .= ' ok<br/>';
        return array('success' => true, 'msg' => $msg);
  }

  public function transferTimeTables() {
    
     $msg = '<b>Time Tables:</b><br/>';
 // time tables      
     $this->Mgr = new TimeTableMgr();
     $this->createFolders('timetabList','timeTable');   
     $TTdir = OLDUSERPATH.TRANSFERUSER."/TT/";
 // get old time tabs  
      $timeTabs = $this->ws->getElementsByTagName('timetab');

      if ($timeTabs->length == 0) {
               return array('success' => true, 'msg' => 'No time tables');
        }

      $obj = new stdClass();

      $ttXML = new DomDocument("1.0");
      foreach ($timeTabs as $item) {   
      
            $obj->name = $item->getElementsByTagName('name')->item(0)->nodeValue;      
            $obj->created = $item->getElementsByTagName('created')->item(0)->nodeValue;                
            $obj->description = $item->getElementsByTagName('condition')->item(0)->nodeValue;
            $obj->history = 'From old AMDA';
            $obj->nodeType = "timeTable";
            $obj->leaf = true;
// intervals
            if (!$ttXML->load($TTdir.$obj->name.".xml")) {
                 $msg .=  'failed to copy '.$obj->name.'<br/>';
                continue;
            }   
        
            $intervals = $ttXML->getElementsByTagName("Interval");
            $ints = array();
            
            foreach ($intervals as $interval){
            				$int = new stdClass();
                $int->start = $interval->getElementsByTagName("Start")->item(0)->nodeValue;
                $int->stop =  $interval->getElementsByTagName("Stop")->item(0)->nodeValue;
                $ints[] = $int;
            }
             $obj->nbIntervals = $intervals->length;

             $this->Mgr->objectDom = new DomDocument("1.0");
            if ($item->parentNode->tagName === 'level1') {
                $folder_id = $item->parentNode->getAttribute('id');
                $res = $this->Mgr->createObject($obj, $folder_id);
            }
            else {
                 $res = $this->Mgr->createObject($obj);
            }            
            
            if ($res['id']) {
                $res = $this->Mgr->saveIntervals($res['id'],$ints,'create');
                if (!$res['success'])
                    $msg .= 'failed copy Time Table '. $obj->name.'<br/>';
              }
            else {
                    $msg .= 'failed copy Time Table '. $obj->name.'<br/>';
            }

        }
      
        $msg .= ' ok<br/>';

        return array('success' => true, 'msg' => $msg);
  }
 
  public function transferConditions() {
     
    $msg = '<b>Conditions:</b><br/>';
    // conditons                
        $this->Mgr = new RequestMgr('condition');
        $condDir = OLDUSERPATH.TRANSFERUSER."/REQ/";
    // get old conditions 
        $conditions = glob($condDir."*.cond");

        if (count($conditions) == 0) {
            return array('success' => true, 'msg' => 'No conditions');
        }

        $obj = new stdClass();
        foreach ($conditions as $item) {  
            $cond = file($item, FILE_IGNORE_NEW_LINES);
            $obj->name = substr(basename($item), 0, -5);
            $expression = $cond[0];

            if ($this->hasAlias($expression)) {
                    $newExp = $this->replaceAliases($expression);  
                    $expression = $newExp;
            }

            if ($this->deleteParam($expression)) {
                  $msg .=  'deleted name:<b>'.$obj->name.'</b>; expression:'.$expression.'<br/>'; 
                    continue;
            }

            $obj->expression = $this->updateParams($expression); 
            $obj->sampling = $cond[1]; 
            $obj->gap = $cond[2]; 
            $obj->description = "From old AMDA";
            $obj->timesrc = "Interval";

            if ($cond[3]) {
				            $obj->startDate = str_replace(":", "-", substr($cond[3],0,10))."T".substr($cond[3],11,8); 
				            $obj->durationDay = "0".substr($cond[4],0,3);
				            $obj->durationHour = substr($cond[4],4,2);
				            $obj->durationMin = substr($cond[4],7,2); 
				            $obj->durationSec = substr($cond[4],10,2); 
            }
            else {
            	    $timestamp = mktime(0, 0, 0, date("m"), date("d")-1, date("Y"));
            	    $obj->startDate = date('Y-m-d\TH:i:s',$timestamp);           	    
            	    $obj->durationDay = "0001";
            	    $obj->durationHour = "00";
            	    $obj->durationMin = "00";
            	    $obj->durationSec = "00";
            }

            $obj->nodeType = "condition";
            $obj->leaf = true;
                      
            $this->Mgr->createObject($obj);             
        }

        $msg .= ' ok<br/>';

       return array('success' => true, 'msg' => $msg);
  }

    public function transferRequests() {

       $msg = '<b>Requests:</b><br/>';
    // requests                
        $this->Mgr = new RequestMgr('request');      
        $reqDir = OLDUSERPATH.TRANSFERUSER."/REQ/";
    // get old requests 
        $requests = glob($reqDir."*.xml");

        if (count($requests) == 0) {
            return array('success' => true, 'msg' => 'No requests');
        }

        $reqXML = new DomDocument("1.0");

        $obj = new stdClass();
        foreach ($requests as $item) { 
 
           if (!$reqXML->load($item)) {
                $msg .= 'failed to copy '.substr(basename($item), 0, -4).'<br/>';
            }           
            $obj->name = substr(basename($item), 0, -4);
            $obj->tabId = 1;
            $obj->outputName = '';
            $obj->orientation = strtoupper($reqXML->getElementsByTagName('orientation')->item(0)->nodeValue);
            $obj->format = 'PNG';
            $obj->title = '';
            $obj->description = 'From old AMDA';
            $obj->charSize = 1.3;
            $obj->thickness = 1;
            $obj->ppp = 3000;
            $obj->forcedLayout = false;
            $obj->forcedMulti = false;
            $obj->timesrc = 'Interval';
            $start = $reqXML->getElementsByTagName('StartTime')->item(0)->nodeValue;
            $obj->startDate = str_replace(":", "-", substr($start,0,10))."T".substr($start,11,8);
            $tint = $reqXML->getElementsByTagName('TimeInt')->item(0)->nodeValue;
            $obj->durationDay = "0".substr($tint,0,3);
            $obj->durationHour = substr($tint,4,2);
            $obj->durationMin = substr($tint,7,2); 
            $obj->durationSec = substr($tint,10,2);
// Panels 
        
            $obj->children = array();
            $panels = array();
                                   
            $params = $reqXML->getElementsByTagName('param');
            foreach ($params as $param) {

                $parId = $param->getAttribute('xml:id');

//check deleted ws_
                if ($this->ws_deleted && strtolower(substr($parId,0,3) == "ws_")) {
                    foreach ($this->ws_deleted as $item) {
                        if ($item === $parId) {
                               $msg .=    'ws param deleted  '.$parId.'<br/>';
                             continue 2;
                        }
                    }
                }

               if (substr($parId,0,3) == "WS_")
                       $parId = strtolower($parId);

                if ($this->deleteParam($parId, true)) {
                   $msg .=    'param deleted  '.$parId.'<br/>'; 
                   continue;
                }  
                $newParId = $this->updateParams($parId, true);  
                $panelNumber = $param->getAttribute('panel'); 
//print_r($obj->name." ".$panelNumber.PHP_EOL);
// no such panel -> create
               if (!$panels[$panelNumber]) {
                    $aPanel = new stdClass();
                    $aPanel->name = 'Panel '.$panelNumber;
                    $aPanel->leaf = false;
                    $aPanel->text = 'Panel '.$panelNumber;
                    $aPanel->width = $param->getAttribute('width');
                    $aPanel->height = $param->getAttribute('height');
                    $aPanel->xTitle = "";
                    $aPanel->xRangeMin = $param->getAttribute('xmin');
                    $aPanel->xRangeMax = $param->getAttribute('xmax');
                    $aPanel->y1Title = "";
                    $aPanel->y1RangeMin = $param->getAttribute('ymin');
                    $aPanel->y1RangeMax = $param->getAttribute('ymax');
                    $aPanel->y2Title = "";
                    $aPanel->y2RangeMin = 0;
                    $aPanel->y2RangeMax = 0;
                    $aPanel->plotType = "TIME";
                    $panels[$panelNumber] = $aPanel;

                    $panels[$panelNumber]->children = array();                       
                }
// add parameter to the panel  
                $aParameter =  new stdClass();
                $aParameter->name = $newParId;
                $aParameter->text = $newParId;
                $aParameter->leaf = true;
                $aParameter->yaxe = false;
//TODO if we need to check this reallY???   
                $aParameter->isScatter = false; 
                $aParameter->needsArgs = false; 
                if ($param->getAttribute('args') === "") 
                    $aParameter->paramArgs = "select...";
                else 
                    $aParameter->paramArgs = $this->convertArgs($newParId, $param->getAttribute('args'));
 
                $panels[$panelNumber]->children[] = $aParameter;
            }
// if there are unordered keys json_encode interprate array as object.... 
            $obj->children = array_values($panels);
            $obj->nodeType = "request";
            $obj->leaf = true;  

          $this->Mgr->createObject($obj).PHP_EOL;             
        }
 
        $msg .= ' ok<br/>';

  return array('success' => true, 'msg' => $msg);
  }

        public function transferMyData() {

           $msg = '<b>My Data:</b><br/>';
// start with copying  DATA dir as it is

           foreach (glob(OLDUSERPATH.TRANSFERUSER.'/DATA/*') as $item) {
                  if (!copy($item, USERDATADIR.basename($item))) {
                                error_log('can\'t copy '.$item,1,email); 
                                $msg .= 'failed copy file '.basename($item).'<br/>';
                    }                   
            }
       
          $filesXml = new DomDocument("1.0");
    
          if (!$filesXml->load($this->wsDir.'files.xml')) $msg .= 'no files.xml <br/>';
          else {

              $fileMgr = new FilesMgr();
              $filesXmlNew = new DomDocument("1.0");
              $root = $filesXmlNew->createElement('ws');
              $filesXmlNew->appendChild($root);
 
              $list = $filesXmlNew->createElement("fileList"); 
              $list->setAttribute("xml:id", "myData-treeRootNode");
              $root->appendChild($list);
 
              $files = $filesXml->getElementsByTagName("file");

              $folders = $filesXml->getElementsByTagName("level1");

              if ($folders->length > 0) 
                foreach ($folders as $folder) {
                  $newFolder = $filesXmlNew->createElement("folder");
                  $newFolder->setAttribute("xml:id", $folder->getAttribute("id"));
                  $newFolder->setAttribute("name", $folder->getAttribute("id"));
                  $list->appendChild($newFolder);
                }
 
              foreach ($files as $file) {
                  $newFile = $filesXmlNew->createElement("file",  $file->getAttribute("title"));
                  $newFile->setAttribute("xml:id", $file->getAttribute("id"));
                  $newFile->setAttribute("name", $file->getAttribute("id"));
                  $format = $file->getElementsByTagName("format")->item(0)->nodeValue;
                  $newFile->setAttribute("format", $format);
                  $newFile->setAttribute("uploaded", $file->getElementsByTagName("uploaded")->item(0)->nodeValue);
                  $newFile->setAttribute("start", $file->getAttribute("start"));
                  $newFile->setAttribute("stop", $file->getAttribute("stop"));
// no sampling for cdf in old amda
                  $minSampling = $file->getAttribute("sampling");
                  $maxSampling = $file->getAttribute("maxsampling");

                  if (!$minSampling) {
                       $minSampling = $this->getSampling(USERDATADIR.$file->getAttribute("id"), $format);
                       $maxSampling = $minSampling;
                   }

                  $newFile->setAttribute("minsampling", $minSampling); 
                  $newFile->setAttribute("maxsampling", $maxSampling); 
//TODO check mask
                  $newFile->setAttribute("mask",  $file->getAttribute("id")); 

                  if ($file->parentNode->tagName == 'level1')
                             $filesXmlNew->getElementById($file->parentNode->getAttribute("id"))->appendChild($newFile);
                  else 
                      $list->appendChild($newFile); 
                 } 
                $filesXmlNew->save(USERWSDIR."Files.xml");
            } 
// mydata parameters                
                $this->Mgr = new DerivedParamMgr('mydataParam');
                $this->createFolders('mydataList','mydataParam');
        //TODO folders are they OK?  
            // get old params  
                $wsdParams = $this->ws->getElementsByTagName('mydata');
               
        //TODO vi ??
             //   $obj = new stdClass();
                foreach ($wsdParams as $item) {
                    $obj = new stdClass();
                    $obj->name = $item->getElementsByTagName('name')->item(0)->nodeValue;
                    $obj->nodeType =  "myDataParam";
                    $obj->leaf = true;
                    $obj->desc = $item->getAttribute('desc');
                    $obj->file = $item->getAttribute('fileOrig');
                    $obj->mask = $item->getAttribute('fileMask');
                    $obj->fillvalue = $item->getAttribute('dataFillValue');
                    $obj->minsampling = $item->getAttribute('dataSampling');
                    $obj->maxsampling = $item->getAttribute('maxSampling');
                    $obj->format = $item->getAttribute('fileFormat');
                    $obj->type = $item->getAttribute('dataType');
                    $obj->size = $item->getAttribute('dataSize');
                    $obj->ytitle = $item->getAttribute('yTitle');
                    $obj->realvar =  $item->getAttribute('realName');
                    $obj->units =  $item->getAttribute('dataUnits');
                    $obj->legend =  $item->getAttribute('dataLegend');

                    $this->Mgr->objectDom = new DomDocument("1.0"); 
                    if ($item->parentNode->tagName === 'level1') {
                            $folder_id = $item->parentNode->getAttribute('id');
                            $this->Mgr->createObject($obj, $folder_id);
                        }
                        else {
                            $this->Mgr->createObject($obj);
                        }
                } 

            $msg .= ' ok<br/>';

         return array('success' => true, 'msg' => $msg);
        }  
}
?>