<?php

if (!extension_loaded('v8js'))
    die("V8Js missing");

if (isset($_POST['editor1']) || isset($_POST['editor2']))
{
    $isOne = isset($_POST['editor1']);

    $source = $isOne ? $_POST['editor1'] : $_POST['editor2'];
    if (!isset($_POST['files']))
        $name = $isOne ? "proc.js" : "main.js";
    else
        $name = $_POST['files'][0];

    header($_SERVER["SERVER_PROTOCOL"] . " 200 OK");
    header("Cache-Control: public"); // needed for i.e.
    header("Content-Type: text/plain");
    header("Content-Transfer-Encoding: Text");
    header("Content-Disposition: attachment; filename=\"".$name."\"");
    print($source);
    return;
}

if (!isset($_POST['file']) || !isset($_POST['event']) || !isset($_POST['pixel']))
{
   /*
    function getList($path)
    {
        $hasdir = false;

        $list = array();
        foreach (new DirectoryIterator($path) as $file)
        {
           if ($file->isDot())
              continue;

           $name = $file->getFilename();


           if ($file->isDir())
           {
               $list[$name] = getList($path."/".$name);
               $hasdir = true;
           }

           if ($file->isFile() && $file->isReadable())
           {
               if (substr($name, 12)!=".fits.fz")
                   continue;

               array_push($list, substr($name, 9, 3));
           }
        }

        if (!$hasdir)
            sort($list);
        return $list;
    }
    */

    function getList($path, $sub)
    {
        $hasdir = false;

        $list = array();
        foreach (new DirectoryIterator($path."/".$sub) as $file)
        {
           if ($file->isDot())
              continue;

           $name = $file->getFilename();

           if ($file->isDir())
               $list = array_merge($list, getList($path, $sub."/".$name));

           if ($file->isFile() && $file->isReadable())
           {
               if (substr($name, 12)!=".fits.fz")
                   continue;

               $rc = substr($name, 0, 4)."/".substr($name, 4, 2)."/".substr($name, 6, 2)."-".substr($name, 9, 3);

               array_push($list, $rc);
           }
        }

        return $list;
    }

    try
    {
        $list = getList("/daq/raw", "");
        sort($list);
    }
    catch (Exception $e)
    {
        return header('HTTP/1.0 400 '.$e->getMessage());
    }

    print(json_encode($list));
    return;
}

$event = intval($_POST['event']);
$pixel = intval($_POST['pixel']);

function get($handle, $format, $count = 1)
{
    $size = 0;
    switch ($format)
    {
    case 'L': $size = 4; break;
    case 'S': $size = 2; break;
    case 's': $size = 2; break;
    }

    if ($size==0)
        return;

    $data = fread($handle, $size*$count);
    $data = unpack($format.$count, $data);

    return $count==1 ? $data[1] : $data;
}

//define('E_FATAL',  E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR |
//        E_COMPILE_ERROR | E_RECOVERABLE_ERROR);

$rc = array();
$rc['startPhp'] = microtime(true);

// ============================ Read data from file ==========================
$file = $_POST['file'];

$y = substr($file,  0, 4);
$m = substr($file,  5, 2);
$d = substr($file,  8, 2);
$r = substr($file, 11, 3);

$filename = "/daq/raw/".$y."/".$m."/".$d."/".$y.$m.$d."_".$r.".fits.fz";

$file = popen("/home/fact/FACT++/getevent ".$filename." ".$event." 2> /dev/null", "r");
if (!$file)
    return header('HTTP/1.0 400 Could not open file.');

$evt = array();

$evt['numEvents']     = get($file, "L");
$evt['numRoi']        = get($file, "L");
$evt['numPix']        = get($file, "L");
$evt['eventNumber']   = get($file, "L");
$evt['triggerNumber'] = get($file, "L");
$evt['triggerType']   = get($file, "S");
$evt['unixTime']      = get($file, "L", 2);

if (isset($_POST['source1']))
{
    // Read the data and copy it from an associative array to an Array
    // (this is just nicer and seems more logical)
    $data = array();
    for ($i=0; $i<$evt['numPix']; $i++)
    {
        //$data[$i] = get($file, "s", $evt['numRoi']);
        $var = get($file, "s", $evt['numRoi']);

        $data[$i] = array();
        for ($j=0; $j<$evt['numRoi']; $j++)
            $data[$i][$j] = $var[$j+1]*0.48828125; // dac -> mV
    }
}

//if (feof($file))
//   return;

pclose($file);

if ($evt['numEvents']==0)
    return header('HTTP/1.0 400 Could not read event.');

// =============================== Copy waveform =============================

$rc['event'] = $evt;
$rc['event']['index'] = $event;
$rc['event']['pixel'] = $pixel;
//$rc['waveform'] = $data[$pixel];

// Get execution times
$now = microtime(true);

if (isset($_POST['source1']))
{
    // =============================== Run Javascript ============================

/*
$JS = <<< EOT
require("path/to/module1");
EOT;

$v8 = new V8Js();
$v8->setModuleLoader(function($module) {
  switch ($module) {
    case 'path/to/module1':
      return 'print(' . json_encode($module . PHP_EOL) . ');require("./module2");';

    case 'path/to/module2':
      return 'print(' . json_encode($module . PHP_EOL) . ');require("../../module3");';

    default:
      return 'print(' . json_encode($module . PHP_EOL) . ');';
  }
});
*/

    // V8Js global methods:  exit, print, sleep, var_dump, require
    //$v8 = new V8Js("$", array("data"=>"data"), extensions, flags, millisecond, bytes);
    $v8 = new V8Js("$"/*, array("data"=>"data")*/);

    //$v8 = new V8Js("$", array("data"=>"data"));

    //V8Js::registerExtension("exit", "1");
    //$v8 = new V8Js("$", array(), array("exit"));

    //$v8->func = function($a) { echo "Closure with param $a\n"; };
    //$v8->greeting = "From PHP with love!";

    // This is much faster than the variables option in the constructor
    $v8->data  = $data;
    $v8->event = $evt;
    $v8->clone = function($data) { return $data; };

    $rc['startJs'] = microtime(true);

    // Buffer output from javascript
    ob_start();

    try
    {
        $JS = "(function proc(pixel){\n".$_POST['source1']."\n})(".$pixel.");";
        $rc['waveform'] = $v8->executeString($JS, 'proc');

        if (isset($_POST['source2']))
        {
            $JS = "(function main(){\n".$_POST['source2']."\n})();";
            $rc['ret'] = $v8->executeString($JS, 'main');
        }

        // This is supposed to work, but it seems it does not...
        //$v8->proc = $rc['ret']->proc;
        //$rc['ret'] = $v8->executeString('PHP.proc();', 'proc');
    }
    catch (V8JsException $e)
    {
        $rc['err'] = array();
        $rc['err']['message']    = $e->getMessage();
        $rc['err']['file']       = $e->getJsFileName();
        $rc['err']['sourceLine'] = $e->getJsSourceLine();
        $rc['err']['lineNumber'] = $e->getJsLineNumber()-1;
        $rc['err']['trace']      = $e->getJsTrace();
    }

    // Copy output buffer and clean it
    $rc['debug'] = ob_get_contents();
    ob_end_clean();

    // Get execution times
    $now = microtime(true);

    $rc['timeJs']  = ($now - $rc['startJs']);
}

$rc['timePhp'] = ($now - $rc['startPhp']);

// Output result as JSON object
print(json_encode($rc));

?>
