<?php

class SystemCheckup
{   
    const GOOD =  array("OK"=>"All Good");
    const ERROR =  array("ERROR"=>"System service is down");
    const DISABLED =  array("DISABLED"=>"Disabled service (not required)");
    
    //add here "func_name"=>"label" for extra checks 
    static $checks_names =array(
            "db_stats"=> "Database",
            "intuscan_stat"=> "IntuScan",
            "search_stat"=>"Search Engine",
            "entityMatcher_stat"=> "Entity Matcher",
            "folderService_stat"=>"Folder Service",
            "solr_stat"=>"Free Text Search",
            "rdfStore_stat"=>"RDF Store",
            "disk_cap_stat"=>"Disk Capacity",
            "disk_perm_stat"=>"File System"
        );
    
            
        //Generic checks if we have connections to the host/port
        public static function is_connected($host, $port, $extra_config=null)
        {
            //file get content / put content
            $start = microtime(true);
            $connected = fsockopen($host, $port);   
            $time_elapsed_secs = microtime(true) - $start;
            write_to_log("TRACE", "SystemCheckup: Host - $host |  port - $port. connection Time check - $time_elapsed_secs\n");
            
          
            if ($connected !== FALSE){
                $is_conn = self::GOOD; 
                fclose($connected);
            }
            elseif (isset($extra_config) && empty($extra_config)){
                $is_conn = self::DISABLED;
            }
            else{
                $is_conn = self::ERROR;
            }
            return $is_conn;
        }
        
        //function that checks if we have connection to the db
        public static function db_stats(){
            //many DB - fix
            global $databaseName;
            $connectionDetails = connectDetails($databaseName);
            $connection = new mysqli($connectionDetails["host"], $connectionDetails["user"], $connectionDetails["pwd"], $connectionDetails["db"], $connectionDetails["port"]);
            if (!$connection || $connection->connect_error){
                return self::ERROR;
            }
            return self::GOOD;
        }
        
        //Intuscan host check
        public static function intuscan_stat()
        {
            //might be many intuscan - check
            $mysqli = sqlCreateConnection("intuscan_stat");
            $intuscanHost = getSystemSettingsProp($mysqli, "intuscanHost");
            $intuscanPort = getSystemSettingsProp($mysqli, "intuscanPort"); 
            sqlClose($mysqli, "intuscan_stat System stats");
            return self::is_connected($intuscanHost,$intuscanPort);
        }
        
        //Intuscan search host check
        public static function search_stat()
        {
            //might be many intuscan - check
        
            $mysqli = sqlCreateConnection("intuscan_stat");
            $intuscanWordHost = getSystemSettingsProp($mysqli, "intuscanWordHost");
            $intuscanWordPort = getSystemSettingsProp($mysqli, "intuscanWordPort");
            sqlClose($mysqli, "intuscan_stat System stats");
            return self::is_connected($intuscanWordHost,$intuscanWordPort);
        }
        
        //Entity Matcher host check
        public static function entityMatcher_stat()
        {
            global $entityMatcherPort;
            $mysqli = sqlCreateConnection("ivEntityMatcherService");
            $ivEntityMatcherService = getSystemSettingsProp($mysqli, "ivEntityMatcherService");
            sqlClose($mysqli, "ivEntityMatcherService System stats");
            
            return self::is_connected($ivEntityMatcherService,$entityMatcherPort);
        }
   
        //RDF check
        public static function rdfStore_stat(){
            global $rdfstoreHost;
            global $rdfstorePort;
            global $isUseRdfStore;
            return self::is_connected($rdfstoreHost,$rdfstorePort,$isUseRdfStore);
        }
        
        //RDF store check
        public static function rdfStorecm_stat(){
            global $rdfstoreCmHost;
            global $rdfstoreCmPort;         
            global $isUseRdfStoreCm;
            return self::is_connected($rdfstoreCmHost,$rdfstoreCmPort,$isUseRdfStoreCm);
        }
        
        //SOLR check
        public static function solr_stat(){
            global $SolRoptions;
            global $SOLR_COLLECTION;
            $mysqli = sqlCreateConnection("solr_stat");    
            $useSolr = getSystemSettingsProp($mysqli, "useSolr");
            sqlClose($mysqli, "useSolr System stats");
            
            if(!$useSolr){
                return self::DISABLED;
            }
            $response = file_get_contents("http://$SolRoptions[hostname]:$SolRoptions[port]/solr/admin/cores?action=status&core=$SOLR_COLLECTION");
            if(!$response){
                return  self::ERROR;
            }
            return self::GOOD;
        }
        
        //Disk capacity check
        public static function disk_cap_stat(){
			global $projectLocalFolder;
            //check permissions for this function
            $df = disk_free_space($projectLocalFolder);
            if($df<1000){ //1MB limit - change if you want
                return self::ERROR;
            }
            return self::GOOD;
        }
        
        //Writing permissions check
        public static function disk_perm_stat(){
            global $projectLocalFolder;
            //change it to the see if we can write to the log            
            if (!is_writable($projectLocalFolder)) {
                
                return self::ERROR;
            }
            return self::GOOD;
        }
        
      
        
        //CheckUp_Flow - runs all the checks at once - output errors
        public static function warnings_checkUp_flow($names){
            $warnings = array();
            foreach($names as $func=>$label){
                
                $stat = self::$func();
                $warnings[$func] = $stat;
            }
            return $warnings;
            
        }
        
        public static function getSystemStatus($mysqli, $username, $request_id = null){
            require_once 'sqlUtils.php';
            $content = CacheEng::get_cache_res($mysqli, array("systemCheckUp","demosettings"), "systemCheckUp", "system_status", $username);
            if(!empty($request_id)){
                $content['id'] = $request_id;
            }
            return $content;
        }
        
        
        public static function system_status( $username){
            require_once 'sqlUtils.php';
            $mysqli = sqlCreateConnection("systemStatus");
            $ret_arr = array();
            $names = self::$checks_names;
      
            $stats_arr =  self::warnings_checkUp_flow($names);
            foreach($names as $key=>$name){
                $element_cond = $stats_arr[$key];
                $status = key($element_cond);
                $cond = $element_cond[$status];
                $detail_per_element = array("key"=>$key,"label"=>$name,"status"=>$status,"message"=>$cond);
                array_push($ret_arr,$detail_per_element);
            }
      
            CacheEng::updateResultsAndCache($mysqli, $username, 'status', 'system_status', $ret_arr);          
            
            //will reset in process
            CacheEng::update_process($mysqli, $username, 'system_status', 0);
            sqlClose($mysqli, "systemStatus");
            return $ret_arr;
        }
        
        public static function folderService_stat(){
            global $dbDetails;
            global $uploadedFilesPath;
            global $CURRENT_SOURCE_FOLDER;
            
            $mysqli = sqlCreateConnection("isFolderService");
            $isFolderService = getSystemSettingsProp($mysqli, "isFolderService");
            $folderServiceHost = getSystemSettingsProp($mysqli, "folderServiceHost");
            $folderServicePort = getSystemSettingsProp($mysqli, "folderServicePort");
            
            sqlClose($mysqli, "isFolderService");
            
            /**Run the request below to the java folder service*/
            if($isFolderService){
                $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                if ($socket === false) {
                    $errorcode = socket_last_error();
                    $errormsg = socket_strerror($errorcode);
                    write_to_log("ERROR", "error with the socket: " . $errormsg);
                    return self::ERROR;
                }
                $ip = $folderServiceHost;
                $result1 = socket_connect($socket, $ip, $folderServicePort);
                if (!$result1) {
                    $errorcode = socket_last_error();
                    $errormsg = socket_strerror($errorcode);
                    write_to_log("ERROR", "Error with checkSystem Status: " . $errormsg);
                    return self::ERROR;
                }

           $req = "<IVEnvelope><checkStatus/></IVEnvelope>";
          
            $result2 = socket_write($socket, $req, strlen($req));
            if ($result2 === false) {
                $errorcode = socket_last_error();
                $errormsg = socket_strerror($errorcode);
                write_to_log("ERROR", "error writing to socket: " . $errormsg);
                return self::ERROR;
            }
            
            //reads the reply envelope from the docserver, in the format of
            //<IVEnvelope>T:# C:# O:#</IVEnvelope> - TOTAL, COUNT, OK-Status
           
            $output = "";
         
            while (true) {
                $read = socket_read($socket, 1024);
                
                if ($read === false) {
                    $errorcode = socket_last_error();
                    $errormsg = socket_strerror($errorcode);
                    write_to_log("ERROR", "error read from socket: " . $errormsg);
                    return self::ERROR;
                }               
                $output = $output . $read;
                $ending = strpos($read, "</IVEnvelope>");
                if ($ending !== false) {//now we know we've read it all
                    write_to_log("TRACE", "Incoming Envelope: " . $output);   
                    break;
                }
            }
            
            socket_close($socket);
            
            
            //check if TOTAL is equal to OK-Status returned
            if (strpos($output, 'Status:true') !== false){
                return self::GOOD;
            }
            return self::ERROR;
        }
        return self::DISABLED; //if not using folder service
      }
            
        
}
