#!/usr/bin/env php
<?php
$replacePath = $argv[0]; //used to figure out where we're running
global $rootPath;
global $session; //store things here you want to reuse
$session = [];

foreach (get_included_files() as $id => $file) {
    if (strpos($file, "vendor" . DIRECTORY_SEPARATOR . "autoload.php")) {
        $rootPath = str_ireplace("vendor" . DIRECTORY_SEPARATOR . "autoload.php", "", $file);
        break;
    }
}

if (empty($rootPath)) {
    $rootPath = str_replace("vendor" . DIRECTORY_SEPARATOR . "tina4stack" . DIRECTORY_SEPARATOR . "tina4php" . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "tina4service", "", __FILE__);
    $rootPath = str_replace("bin" . DIRECTORY_SEPARATOR . "tina4service", "", $rootPath);
}

require_once "{$rootPath}vendor/autoload.php";
define("TINA4_SUPPRESS", true);

if (file_exists($rootPath . "index.php")) {
    include_once $rootPath . "index.php";
}

$stopFileName = "{$rootPath}stop";
if (file_exists($stopFileName)) {
    unlink($stopFileName);
}

\Tina4\Debug::message("Running from folder {$rootPath}", TINA4_LOG_INFO);
\Tina4\Debug::message("Running Tina4 service", TINA4_LOG_INFO);

//Garbage collection
gc_enable();

while (TRUE && !file_exists($stopFileName)) {
    $service = new \Tina4\Service();
    $processes = $service->getProcesses();
    sleep($service->getSleepTime());
    if (!empty($processes)) {
        foreach ($processes as $id => $process) {
            try {
                if (get_class($process) !== "__PHP_Incomplete_Class") {
                    try {
                        //How to know we are not on server?
                        if (TINA4_DEBUG) {
                            \Tina4\Debug::message("Running {$process->name}", TINA4_LOG_INFO);

                            $reflection = new \ReflectionClass(get_class($process));
                            $code = file_get_contents($reflection->getFileName());
                            $code = str_replace('<?php', '', $code);
                            $aliasNumber = rand(1000, 9999);


                            if (isset($settings[$process->name]) && $settings[$process->name]["hash"] == md5($code)) {
                                $aliasNumber = $settings[$process->name]["instance"];
                            } else {
                                $settings[$process->name]["hash"] = md5($code);
                                $settings[$process->name]["instance"] = $aliasNumber;

                                //Works when name space is used
                                $className = explode(DIRECTORY_SEPARATOR, get_class($process));
                                $className = $className[count($className) - 1];

                                $code = str_replace($className, $className . $aliasNumber, $code);
                                //Load new class
                                \Tina4\Debug::message(date("Y-m-d H:i:s") . " Reloading code for service {$className} \n{$code}", TINA4_LOG_DEBUG);
                                eval($code);
                            }

                            eval('$runner = new ' . get_class($process) . $aliasNumber . "('{$process->name}');");
                            if ($runner->canRun()) {
                                \Tina4\Debug::message(date("Y-m-d H:i:s") . " Running {$process->name}", TINA4_LOG_DEBUG);
                                $runner->run();
                            }
                            unset ($runner);
                            $runner = null;
                        } else {
                            if ($process->canRun()) {
                                \Tina4\Debug::message(date("Y-m-d H:i:s") . " Running {$process->name}");
                                $process->run();
                            }
                            unset($process);
                        }
                    }
                        catch (\Exception $exception)
                    {
                        \Tina4\Debug::message("Exception happened in service:\n".$exception->getMessage());
                    }

                    gc_collect_cycles();
                } else {
                    \Tina4\Debug::message("Could not load registered process, make sure it is in one of the TINA4_INCLUDE_LOCATIONS", TINA4_LOG_DEBUG);
                }
            } catch (Exception $exception) {
                \Tina4\Debug::message(date("Y-m-d H:i:s") . " Could not run " . $exception->getMessage(), TINA4_LOG_DEBUG);
            }
        }
    } else {
        \Tina4\Debug::message(date("Y-m-d H:i:s") . " Nothing found to run", TINA4_LOG_DEBUG);
    }
    //clean up
    unset($service);
}