<?php
// sass_watchdog.php
// RJM Programming
// Optionally helps out sass --watch [inputSassSCSS] [outputCSS]

$incssfiles=["  "];
$outcssfiles=["   "];
$curlurl=["         "];
$phppath=["          "];
$logfiles=["    "];
$errlogfiles=["     "];
$results=["       "];
$amrunning=["       "];
$sasexe=["        "];
$sasswitch=[" --watch "];
$fn='';
$swis='';
$upd=false;
$preone=1;
$onerest='';
$rest='';
$checkbit='';
$updword='Start';
$repis='';
$scrbit='';

if (sizeof($incssfiles) > 1) {
  $checkbit="<input type=hidden name=check value=''></input>";
  $updword='Update';
}

if (isset($argc)) {
  $fn=$argv[0];
  $swis=file_get_contents($fn);
} else {
  $fn=dirname(__FILE__) . "/sass_watchdog.php";
  $swis=file_get_contents($fn);
  if (strpos($swis,'" ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' "') !== false) {
    $swis=str_replace('" ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' "', '"http://' . $_SERVER['SERVER_NAME'] . "" . str_replace("~","",str_replace(":443~","",str_replace(":80~","",(":" . $_SERVER['SERVER_PORT'] . "~")))) . "" . explode("#", explode("?", $_SERVER['REQUEST_URI'])[0])[0] . '"', $swis);
    $curlurl[0]='http://' . $_SERVER['SERVER_NAME'] . "" . str_replace("~","",str_replace(":443~","",str_replace(":80~","",(":" . $_SERVER['SERVER_PORT'] . "~")))) . "" . explode("#", explode("?", $_SERVER['REQUEST_URI'])[0])[0];
    $upd=true;
  }
  if (strpos($swis,'" ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' "') !== false) {
    if (PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows') {
    $swis=str_replace('" ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' "', '"' . dirname(__FILE__) . substr("\\",0,1) . 'sass_watchdog.php' . '"', $swis);
    $phppath[0]=dirname(__FILE__) . substr("\\",0,1) . 'sass_watchdog.php';
    } else {
    $swis=str_replace('" ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' ' . ' "', '"' . dirname(__FILE__) . '/sass_watchdog.php' . '"', $swis);
    $phppath[0]=dirname(__FILE__) . '/sass_watchdog.php';
    }
    $upd=true;
  }
}

// Thanks to https://gist.github.com/lsauer/6476476
// # www.lsauer.com, 2012 lo sauer
// # desc: kill a process on Linux, MacOS, Windows without a process-control library
// #      in the php setup or environment

$kill = function($pid){ return stripos(php_uname('s'), 'win')>-1 
                        ? exec("taskkill /F /PID $pid") : exec("kill -9 $pid");
};

//e.g.
//echo $kill(19008);
//> "Successfully terminated...."
//array_map($kill, [19008,23012,1802,930]);
//killall: without using array_map and a boolean return value

$killall = function($pids){ $os=stripos(php_uname('s'), 'win')>-1; 
                           ($_=implode($os?' /PID ':' ',$pids)) or ($_=$pids);
                           return preg_match('/success|close/', 
                           $os ? exec("taskkill /F /PID $_") : exec("kill -9 $_"));
};

//if( $killall([19008,23012,1802,930]) and $killall(19280)){
//  echo "successfully killed all processes"
//}
//  /usr/local/Cellar/sass/1.22.12/bin/sass --watch /Applications/MAMP/htdocs/sass/base.scss /Applications/MAMP/htdocs/sass/build/test.css >> /Applications/MAMP/htdocs/sass/sass_watch.ok 2>> /Applications/MAMP/htdocs/sass/sass_watch.notok & 

function ourrealpath($inid) {
  if (realpath($inid) != $inid && realpath($inid) != '') {
    return realpath($inid);
  }
  return $inid;
}

//Note for windows users:
//You cannot redirect stdout/stderr to nul in the following manner:
//startBackgroundProcess('ping yandex.com', null, 'nul', 'nul');
//However, you can do this:
//startBackgroundProcess('ping yandex.com >nul 2>&1');

function startBackgroundProcess(
    $commandin,
    $stdin = null,
    $redirectStdout = null,
    $redirectStderr = null,
    $cwd = null,
    $env = null,
    $other_options = null
) {  // thanks to https://stackoverflow.com/questions/45953/php-execute-a-background-process

    global $incssfiles, $outcssfiles, $logfiles, $errlogfiles,$amrunning,$sasexe, $swis, $fn, $upd; 

    $command=str_replace(" " . " "," ",str_replace(" " . " " . " "," ",$commandin));
    $four=4;
    
    $trunning = false;  
    $proc = null;
    $isthere = true; 
    
    $cwords=explode(' ', str_replace(" " . " "," ",str_replace(" " . " " . " "," ",$commandin)));
    if (sizeof($cwords) > 1) {
      if (substr($cwords[1],0,1) != '-') { $four=3; }
    }
    if (sizeof($cwords) >= $four) {
      if ($four == 4) {
      $command=$cwords[0] . ' ' . $cwords[1] . ' ' . ourrealpath($cwords[2]) . ' ' . ourrealpath($cwords[3]);
      } else {
      $command=$cwords[0] . ' ' . ourrealpath($cwords[1]) . ' ' . ourrealpath($cwords[2]);
      }
      for ($ii=$four; $ii<sizeof($cwords); $ii++) {
        $command.=' ' . $cwords[$ii];
      }
    } 
    
    if (strpos($swis, $command) !== false) {
       $tpid=explode(",",explode("|" . str_replace(" ",";",explode($sasswitch[0], $command)[1]) . ",", $swis)[0])[-1 + sizeof(explode(",",explode("|" . str_replace(" ",";",explode($sasswitch[0], $command)[1]) . ",", $swis)[0]))];
       if (PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows') {
       if (file_exists(str_replace("sass_watchdog.php", "swjunk.jnk", $fn))) {
         unlink(str_replace("sass_watchdog.php", "swjunk.jnk", $fn));
       }
       exec('tasklist /fi "pid eq ' . $tpid . '" > ' . str_replace("sass_watchdog.php", "swjunk.jnk", $fn));
       if (file_exists(str_replace("sass_watchdog.php", "swjunk.jnk", $fn))) {
         $tlout=file_get_contents(str_replace("sass_watchdog.php", "swjunk.jnk", $fn));
         unlink(str_replace("sass_watchdog.php", "swjunk.jnk", $fn));
         if (strpos($tlout, ' ' . $tpid . ' ') !== false) {
           $trunning = true;   
         }
       }
       } else {
       $trunning = posix_kill($tpid,0);
       }
       if ($trunning) {  
        return null;  
       } else {
        $swis=str_replace("," . $tpid . "|" . str_replace(" ",";",explode($sasswitch[0], $command)[1]), '', $swis);
        $upd=true;
       }
    }

    $cwords=explode(' ', $command);
    if (sizeof($cwords) >= $four) {
       if (!file_exists($cwords[-2 + $four])) { // not good
         $isthere=false;
       }
    } else {
       $isthere=false;
    }
    
    $descriptorspec = array(
        1 => is_string($redirectStdout) ? array('file', $redirectStdout, 'w') : array('pipe', 'w'),
        2 => is_string($redirectStderr) ? array('file', $redirectStderr, 'w') : array('pipe', 'w'),
    );
    if (is_string($stdin)) {
        $descriptorspec[0] = array('pipe', 'r');
    }
    if ($isthere) { 
        $proc = proc_open($command, $descriptorspec, $pipes, $cwd, $env, $other_options); 
    } 
    if (!is_resource($proc)) {
        //throw new \Exception("Failed to start background process by command: $command");
        $proc=null;
    } else {
        $etat=proc_get_status($proc);
        if ($etat['running'] == FALSE) {
            proc_close($proc);
            $proc=null;
            return null;
        } else {
            $swis=str_replace("," . ",", "," . $etat['pid'] . "|" . $cwords[-2 + $four] . ";" . $cwords[-1 + $four] . "," . ",", $swis);
            $upd=true;
            $swis=str_replace('["' . ' ' . ' ' . '"]', '["' . $cwords[-2 + $four] . '","' . ' ' . ' ' . '"]', str_replace(',"' . ' ' . ' ' . '"]', ',"' . $cwords[-2 + $four] . '","' . ' ' . ' ' . '"]', $swis));
            $swis=str_replace('["' . ' ' . ' ' . ' ' . '"]', '["' . $cwords[-1 + $four] . '","' . ' ' . ' ' . ' ' . '"]', str_replace(',"' . ' ' . ' ' . ' ' . '"]', ',"' . $cwords[-1 + $four] . '","' . ' ' . ' ' . ' ' . '"]', $swis));
        }
    }
    if (is_string($stdin)) {
        fwrite($pipes[0], $stdin);
        fclose($pipes[0]);
    }
    if (!is_string($redirectStdout)) {
        fclose($pipes[1]);
    }
    if (!is_string($redirectStderr)) {
        fclose($pipes[2]);
    }
    
    return $proc;
}

if (!function_exists("readline")) {  // thanks to https://stackoverflow.com/questions/23238378/call-to-undefined-function-readline
    function readline($prompt = null) {
        if ($prompt) {
            echo $prompt;
        }
        $fp = fopen("php://stdin","r");
        $line = rtrim(fgets($fp, 1024));
        return $line;
    }
}

if (!isset($argc)) {  // surfing the net
 if (isset($_POST['check']) && isset($_POST['in1out1'])) {
   while (isset($_POST['in' . $preone . 'out' . $preone])) {
     if ($prerest == '') {
       $prerest=str_replace('+',' ',urldecode($_POST['in' . $preone . 'out' . $preone]));
       $preone++;
     } else {
       $rest.="<tr><td id=mytd" . $preone . " style=width:100%;><input style='width:99%;' id=in" . $preone . "out" . $preone . " onblur=add(this); name=in" . $preone . "out" . $preone . " value='" . str_replace('+',' ',urldecode($_POST['in' . $preone . 'out' . $preone])) . "' placeholder='Separate with ; (or space) an [inputSassSCSS];[outputCSS] fileset'></input></td></tr>";
       $preone++;
     }
   }
   if ($prerest != '')  {
     $rest.="<tr><td id=mytd" . $preone . " style=width:100%;><input style='width:99%;' id=in" . $preone . "out" . $preone . " onblur=add(this); name=in" . $preone . "out" . $preone . " value='' placeholder='Separate with ; (or space) an [inputSassSCSS];[outputCSS] fileset'></input></td></tr>";
   }
 }
 
 if (isset($_GET['check'])) {
 } else if (isset($_GET['in1']) && isset($_GET['out1'])) {
 } else if (isset($_POST['in1out1']) && !isset($_POST['check'])) {
   $scrbit=
   $cmds='/usr/local/Cellar/sass/1.22.12/bin/sass';
   if (isset($_POST['sasexe'])) {
      if (strlen(trim($_POST['sasexe'])) != 0) {
       if (realpath(str_replace('+',' ',urldecode($_POST['sasexe']))) != '') {
        $cmds=realpath(str_replace('+',' ',urldecode($_POST['sasexe'])));
       } else {
        $cmds=str_replace('+',' ',urldecode($_POST['sasexe']));
       }
      } else {
       $cmds="sass";
      }
   }
   $cmdsw=' --watch ';
   if (isset($_POST['sasswitch'])) {
      if (strlen(trim($_POST['sasswitch'])) != 0) {
        $cmdsw=str_replace('+',' ',urldecode($_POST['sasswitch']));
      }
   }
   if (PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows') {
      $lfil='nul';
      $errlfil='&1';
   } else {
      $lfil='/dev/null';
      $errlfil='/dev/null';
   }
   if (isset($_POST['errlogfiles'])) {
      if (strlen(trim($_POST['errlogfiles'])) != 0) {
       if (ourrealpath(str_replace('+',' ',urldecode($_POST['errlogfiles']))) == '') {
        $errlfil=str_replace('+',' ',urldecode($_POST['errlogfiles']));
       } else {
        $errlfil=ourrealpath(str_replace('+',' ',urldecode($_POST['errlogfiles'])));
       }
      }
   }
   if (isset($_POST['logfiles'])) {
      if (strlen(trim($_POST['logfiles'])) != 0) {
       if (ourrealpath(str_replace('+',' ',urldecode($_POST['logfiles']))) == '') {
        $lfil=str_replace('+',' ',urldecode($_POST['logfiles']));
       } else {
        $lfil=ourrealpath(str_replace('+',' ',urldecode($_POST['logfiles'])));
       }
      }
   }
   $one=$preone;
   while (isset($_POST['in' . $one . 'out' . $one])) {
   if (strlen($_POST['in' . $one . 'out' . $one]) > 0) {
    //if (sizeof($incssfiles) > $one) {
     if (PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows') {
       if (strpos($_SERVER['SERVER_NAME'], "rjmprogramming.com.au") === false) { 
        if (!startBackgroundProcess($cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil)) {
          echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Errors calling ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
        } else {
          echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Successfully called ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
        }
       } else {
        echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Would have tried to call ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
       }
     } else {
       if (strpos($_SERVER['SERVER_NAME'], "rjmprogramming.com.au") === false) { 
        if (!startBackgroundProcess($cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil)) {
         echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Errors calling ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
        } else {
         echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Successfully called ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
        }
       } else {
        echo str_replace("\n","<br>",str_replace(">","&gt;",str_replace("<","&lt;","Would have tried to call ... startBackgroundProcess('" . $cmds . ' ' . $cmdsw . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[0] . ' ' . explode(' ',str_replace(';', ' ',str_replace('+',' ',urldecode($_POST['in' . $one . 'out' . $one]))))[1] . ' >> ' . $lfil . ' 2>> ' . $errlfil . "');\n")));
       }
     }
    //}
    }
    $one++;
   }
   if ($upd) { file_put_contents($fn, $swis); }
 } else {
  echo "<!doctype html>
<html>
<head>
<script type='text/javascript'>
 var atthis=" . $preone . ";
 var inputtemp='';
 var vals=[];
 function add(oin) {
   if (inputtemp == '') {
     inputtemp=oin.outerHTML;
     oin.value='" . $onerest . "'; 
     document.getElementById('in' + atthis + 'out' + atthis).focus();
   }
   if (oin.value.replace(' ',';').indexOf(';') != -1) {
     vals.push(oin.value.replace(/\ \ \ /g,' ').replace(/\ \ /g,' '));
     atthis++;
     document.getElementById('mytbody').innerHTML+='<tr><td id=mytd' + atthis + ' style=width:100%;>' + inputtemp.replace(/1/g, '' + atthis) + '</td></tr>';
     for (var i=0; i<eval(-1 + atthis); i++) {
       document.getElementById('in' + eval(1 + i) + 'out' + eval(1 + i)).value=vals[i];
     }
     document.getElementById('in' + atthis + 'out' + atthis).focus();
   }
 }
</script>
</head>
<body onload=\"add(document.getElementById('in1out1'));\">
<h1>Sass 'sass --watch [inputSassSCSS] [outputCSS]' Supervisor and Watchdog</h1>
<h3>RJM Programming</h3>
<h3>September, 2019</h3>
<form id=myform action=./sass_watchdog.php method=POST>
<table style='width:90%;' id=myexetable border=5><tbody id=myexetbody>
<tr id=myexetr>
<td id=myexetd1 style='width:75%;'><input style='width:100%;' name=sasexe value='/usr/local/Cellar/sass/1.22.12/bin/sass' placeholder='Sass sass executable path'></input></td>
<td id=myswitchtd1 style='width:25%;'><input style='width:100%;' name=sasswitch value=' --watch ' placeholder='Sass sass executable switch'></input></td>
</tr>
</tbody>
</table>
<br><br><table style='width:90%;' id=mytable border=5><tbody id=mytbody>
<tr id=mytr><td id=mytd1 style='width:100%;'>
<input style='width:99%;' id=in1out1 onblur=add(this); name=in1out1 value='' placeholder='Separate with ; (or space) an [inputSassSCSS];[outputCSS] fileset'></input>
</td></tr>" . $rest . "
</tbody>
</table>
<br><br>
<table style='width:90%;' id=mylogtable border=5><tbody id=mylogtbody>
<tr id=mylogtr>
<td id=mylogtd1 style='width:50%;'><input style='width:100%;' name=logfiles value='' placeholder='Append to this logfile'></input></td>
<td id=mylogtd2 style='width:50%;'><input style='width:100%;' name=errlogfiles value='' placeholder='Append to this error logfile'></input></td>
</tr>
</tbody>
</table>
<br><br><input style='background-color:yellow;' type=submit id=mysubmit value='" . $updword . " Watchdog for Above'></input>" . $checkbit . "
</form>
<input style='position:absolute;top:-200px;left:-200px;' type=text value=''></input>
</body>
</html>";
 }
} else {  // command line
 $swis=$swis;
}

// Logging information below 
// ,,
?>
