<?php

if (session_status() == PHP_SESSION_NONE) {
    if(!isset($_SESSION)) session_start();
}

include("loginCheckPoint.php");
require_once("demosettings.php");
include_once 'write_log.php';
require_once 'sqlUtils.php';
require_once 'asyncRequst.php';
require_once 'parseUtils.php';
require_once 'OSSpecific.php';




function sendFolderProcess($mysqli, $username, $isAdmin, $manual_data = null){
//     session_write_close(); 
    global $splitWithoutGlobal;
    $isFolderService = getSystemSettingsProp($mysqli, "isFolderService");

    $data = $manual_data ?? file_get_contents('php://input');
    $sent_data = json_decode($data,1); //data from request payload from the UI
    $params_env = $params = null;
    if(!empty($sent_data)){
        $folderPath = $sent_data['folder'];
        
        //params from ui to attach to each file
        $params = json_encode($sent_data['attach'],true); //for tags
        $params = $mysqli->real_escape_string($params);
        $params_env = base64_encode($params);
        
    }
    
    if(empty($folderPath)) { //also defined in autoSendFolder.php
        $folderPath = filter_input(INPUT_GET, "folderPath");
    }
    
    if(empty($folderPath)){
        return array("ERROR"=>"Empty path of folder");
        
        
    }
    
    $isEmail =   $sent_data['isEmail'] ?? $sent_data['emailCorrespondences'] ?? null;
    $split =   $sent_data['split'] ?? null;
    $split_without =   $sent_data['splitWithout'] ?? $splitWithoutGlobal;
    
    
    $canAnalyzeFolder = getUserPermission(CAN_ANALYZER_FOLDER);
    if (!$canAnalyzeFolder) {
        die("User is not authorized to analyze folders");
    }

    if($split && empty($manual_data)){
        require_once '..'.DIRECTORY_SEPARATOR.'pdfTools.php';    
        $pdf_tools = new PDFTools();
        $date = date("d_m_Y_H_i_s");
        $stamp = '_'.$username.'_'.$date.'';
        
        $absPath = uploadedFileAbsolutPath($folderPath);
        
        $pdf_tools->recurse_copy($absPath, $absPath.$stamp);
        
        $pdf_tools->splitProcess($mysqli, $absPath.$stamp);
        
        $folderPath .= $stamp;
        
        if($split_without){
            return "finished preparing the folder";
        }
        
    }
    $fid = null;
    if($isFolderService) { 
        $arr = sendFolderDocServer($mysqli, $params_env, $folderPath, $isEmail, $username, $isAdmin);
        return array("fid"=> $arr["fid"], "fname" => $arr["fname"]);
        
    }
    else{ 
        $arr = sendFolderDSOff($mysqli, $folderPath, $params, $isEmail, $username, $isAdmin);
        return array("fid"=> $arr["fid"], "fname" => $arr["fname"]);
        
    }
}



/**Run the request below to the java folder service*/	
function sendFolderDocServer($mysqli, $params_env, $folderPath, $isEmail, $username, $isAdmin){
    global  $docserverPath, $docserverxmlpath, $docserversourcefolder;
    global $databaseName;
    global $metadata_path;
    global $uploadedFilesPath;
    
    write_to_log("INFO", "Running with doc server");
    $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 writing to socket: " . $errormsg);
        return false;
    }
    
    $folderServiceHost  = getSystemSettingsProp($mysqli, "folderServiceHost");
    $folderServicePort = getSystemSettingsProp($mysqli, "folderServicePort");
    $result1 = socket_connect($socket, $folderServiceHost, $folderServicePort);
    if ($result1 === false) {
        $errorcode = socket_last_error();
        $errormsg = socket_strerror($errorcode);
        write_to_log("ERROR", "Error writing to FolderService [host:$folderServiceHost port:$folderServicePort]: " . $errormsg);
        return false;
    }
    
    $path = $docserverPath;
    $xmlpath = $docserverxmlpath; 
    $sourchFolder = $docserversourcefolder; 
    
    $dbDetails = connectDetails($databaseName);
    $req = sprintf("<IVEnvelope><AnalyzeFolder 
		params='%s' 
		uploadedFilesPath=\"%s\" 
		path=\"%s\" 
		username=\"%s\" 
		sourcePath=\"%s\" 
		xmlResults=\"%s\" 
        db_username=\"%s\"
		db_password=\"%s\"
		db_name=\"%s\"
		db_host=\"%s\"
		db_port=\"%s\"
        isEmail=\"%s\"/></IVEnvelope>",			
        $params_env,
		$path,
		$folderPath,
		$username,
		$sourchFolder,
		$xmlpath,
		$dbDetails["user"],
		$dbDetails["pwd"],
		$dbDetails["db"], 
		$dbDetails["host"],
		$dbDetails["port"],
        $isEmail);		
	
    $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 false;
    }


    $output = "";
    $numRetries = 0;
    while (true) {

        $read = socket_read($socket, 1024);
        if ($read === FALSE) {

            if ($numRetries++ < 3) {

                sleep(1);
                continue;
            } else {

                $errorcode = socket_last_error();
                $errormsg = socket_strerror($errorcode);
                write_to_log("ERROR", "error reading from socket: $errormsg");
                return false;
            }
        }
        $output = $output . $read;
        $ending = strpos($output, "</IVEnvelope>");
        if ($ending !== false) {
            break;
        }
    }

    $IVEnvelope = simplexml_load_string($output);
    $replyUsername = (string) $IVEnvelope->Reply['username'];
    $id_arr = (getFolderIdFromName($mysqli, $folderPath, $username, $isAdmin)); //get last id of folder that match the username & name
//     wait until we get the id of the last folder
    $tries = 0;
    while(empty($id_arr) && $tries < 5){
        write_to_log("INFO","waiting for the folder id to updated - sleep 5 seconds");   
        sleep(5);
        $tries++;
        $id_arr = (getFolderIdFromName($mysqli, $folderPath, $username, $isAdmin)); //get last id of folder that match the username & name     
    }
    $fid = !empty($id_arr) ? array_slice($id_arr, -1)[0] : null;
    
//     $id = end($id_arr);
    
//     $total_count = 0; 
//     $scan_count = 0;
    
//     while($total_count !== $scan_count  || ($scan_count==0 & $total_count == 0)){
//         $analysing_stat = getFolderAnalyseStatus($mysqli, [$id]);
//         $total_count = $analysing_stat["total"];
//         $scan_count = $analysing_stat["analysed"];
//         $no_timestamp_count = $analysing_stat["no_timestamp"];
//         $text =  json_encode($analysing_stat, true);
//         sendResponse($text);
//         if($no_timestamp_count == 0){
//             write_to_log("INFO","All files have timestamp - return as it is");
//             break;
//         }
//         sleep(2);
        
//     }
//     write_to_log("INFO","Analysed: $scan_count, total documents: $total_count, noTimeSamp: $no_timestamp_count");
    
    return ["fname"=>$folderPath, "fid" => $fid];

 
}

function sendResponse($text){
    ob_end_clean();
    header("Connection: close");
    ignore_user_abort(); // optional
    ob_start();
    echo $text;
    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush(); // Strange behaviour, will not work
    flush();            // Unless both are called !
    session_write_close(); // Added a line suggested in the comment
    // Do processing here

}

function getSubFoldersids($mysqli, $id){
    
    $results = [];
    $sql = "SELECT id FROM foldertree WHERE parentId=$id ";
    $res = sqlQuery($mysqli, $sql);
    while($obj = $res->fetch_object()){
        $son_id = $obj->id;
        $results[] = $son_id;
        $results = array_merge($results, getSubFoldersids($mysqli, $son_id));
    }
    return $results;
}

function getFoldersStatus($mysqli, $username, $isAdmin){
    global $foldersStatusLimit;
    $response = [];

    $sql_user = !$isAdmin ? "username= \"$username\"" : " TRUE ";
    $sql = "SELECT DISTINCT origfolder as f FROM files WHERE $sql_user";

    $res = sqlQuery($mysqli, $sql);
    while($obj = $res->fetch_object()){
        $arr = explode(DIRECTORY_SEPARATOR, $obj->f);
        $origFolderArr[] = $arr[0];
    }
    $origFolderArr = array_unique($origFolderArr ?? []);
    $origFolderStr = join("','",$origFolderArr);
    if(empty($origFolderStr)){
        return [];
    }
    $sql = "SELECT id,name FROM foldertree WHERE $sql_user AND NAME IN 
            ('$origFolderStr')
            ORDER BY ID DESC LIMIT $foldersStatusLimit";
    $res = sqlQuery($mysqli, $sql);
    while($obj = $res->fetch_object()){
      $id = $obj->id; 
      $subFoldersArr = getSubFoldersids($mysqli, $id) ?? [];
      array_push($subFoldersArr, $id);
      $name = $obj->name;
      $status_arr = getFolderAnalyseStatus($mysqli, $subFoldersArr);
        if($status_arr["no_timestamp"] > 0){
          $status = "In Process";
      }
      elseif($status_arr["no_timestamp"] == 0 && !empty($status_arr["error_docs"])){
          $status = "Done - error in docs: ".$status_arr["error_docs"];      
      }
      else{
          $status = "Done";       
      }
//       $status = ($status_arr["no_timestamp"] == 0) ? "Done" : "In Process";
      $response[] = ["id"=>$id, "name"=>$name, "status"=>$status, "status_arr"=>$status_arr];
    }
    return $response;
}
/**
 * get folder analytic status - scan_time count, total count and timestamp count.
 * @param unknown $mysqli
 * @param unknown $id
 * @return unknown[]
 */
function getFolderAnalyseStatus($mysqli, $subFolderArr){
    $ids_str = implode(',', $subFolderArr);
    $sql = "SELECT count(id) as c, count(scan_time)  as s, min(file_creation_date) as d FROM files WHERE parentFolderId IN ($ids_str)";
    $res = sqlQuery($mysqli, $sql);
    $obj = $res->fetch_object();
    if(!empty($obj)){
        $total_count = $obj->c;
        $scan_count = $obj->s;
        $date = $obj->d;
        
    }
    write_to_log("INFO","Analysed $scan_count out of $total_count");
    
    $sql = "SELECT COUNT(id) AS count FROM files WHERE parentFolderId IN ($ids_str) AND TIMESTAMP IS NULL";
    $res = sqlQuery($mysqli, $sql);
    $obj = $res->fetch_object();
    $no_timestamp_count = $obj->count;
    
    $sql = "SELECT group_concat(id) AS error_docs FROM files WHERE parentFolderId IN ($ids_str) AND (id IN 
            (SELECT docid FROM filetags WHERE groupName = \"system_tags\" AND NAME = \"error_send_doc\")) "; 
    $res = sqlQuery($mysqli, $sql);
    $obj = $res->fetch_object();
    $error_docs = $obj->error_docs;

    
    write_to_log("INFO","$no_timestamp_count files with no timestamp, files with errors: " . $error_docs);
    
    return ["total"=> intval($total_count), "analysed" => intval($scan_count), "date" => $date,  "no_timestamp" => intval($no_timestamp_count), "error_docs" => $error_docs];
}

function sendFolderDSOff($mysqli, $folderPathOrg, $params, $isEmail, $username, $isAdmin){
    global $PHP_FOLDER, $CURRENT_SOURCE_FOLDER;
    $intuscanHost = getSystemSettingsProp($mysqli, "intuscanHost");
    $intuscanPort = getSystemSettingsProp($mysqli, "intuscanPort"); 
    $intuscanArray = array("$intuscanHost:$intuscanPort");
    
    write_to_log("INFO","sendFolder running without doc server on $folderPathOrg");	
	if(!empty($groupTag) || !empty($tag)) {
            write_to_log("ERROR","Tagging uploaded folder not supported w/o Folder-service");
        }
    $folderPath = uploadedFileAbsolutPath($folderPathOrg);
        
	
	$dir = OSSpecific::getInstance()->getDirectoryIterator($folderPath);
	
	$sql = "UPDATE user_status SET isRunning=1 WHERE username=\"$username\"";
	$res = sqlQuery($mysqli, $sql);
	
	
	$numOfIntuscan = count($intuscanArray);
	
	$folderScanDate = str_replace('+', ' ', date(DATE_ATOM));

	$i = 0;	
	//$sql = "SET @numErrors = 0;\r\n";
	$sql = "";
	$prevFolder = "";
	
	foreach ($dir as $fn) {
		$fileName = $mysqli->real_escape_string($fn->getFilename());
		
		$shortFileName = $mysqli->real_escape_string($fn->getShortFilename());
		$subfolderPath = uploadedFileRelativePath(realpath($fn->getPath()));
		$folderPathSql = $mysqli->real_escape_string($subfolderPath);
		$dateColumns = "";
		$dateValues = "";
		foreach (array("ctime" => "file_creation_date", "mtime" => "file_last_modified_date", "atime" => "file_last_accessed_date") as $key => $column)
		{
			$stat = $fn->getStat();
			if (!$stat || !array_key_exists($key, $stat))
				continue;
			
			$dateColumns .= ", $column";
			$dateValues .= ", '" . date('Y-m-d H:i:s', $stat[$key]) ."'";
		}
		
		$userId = getUserId($mysqli,$username,$userId ?? null,$i);
	    $sql .= "INSERT INTO files (username, filename, shortFileName, origFolder $dateColumns,userId,results) VALUES ('$username', '$fileName', '$shortFileName', '$folderPathSql' $dateValues,$userId,'$params');\r\n";


		$sql .= "SET @docId = LAST_INSERT_ID();\r\n";
		$insertFolders = $prevFolder != $folderPathSql;
		$prevFolder = $folderPathSql;
		$sql .= createSqlInsertDocPath($mysqli, "@docId", $subfolderPath, $folderScanDate, $username, $insertFolders);

		$i++;
		//if ($i >= 1000) //sometimes mysql server is "gone away" for a bulk of 1000 inserts, and reducing inserts to 100 helps
		if ($i >= 100)
		{
			sqlMultiQuery($mysqli, $sql);
			$sql = "";
			$i = 0;
		}
    }
    if ($i) {
            sqlMultiQuery($mysqli, $sql);
    }

    $file_id = 1;
	foreach ($intuscanArray as $ip_port_str){
		$ip_port = explode(":", $ip_port_str, 2);
		$serverIP = $ip_port[0];
		$port = $ip_port[1];
		$i = 1;
		while ($i <= 3){        	
			write_to_log("INFO", "current senddoc folder: $CURRENT_SOURCE_FOLDER");
                        asyncRequst::getInstance()->sendDocAsync($PHP_FOLDER, $i, $username, $serverIP, $port, $file_id, $isEmail);
                
			$i++;
		}
		//if ($file_id == 1)
		//	pclose(popen("start /B $CURRENT_SOURCE_FOLDER\\ExtractNamesFromEmails.bat \"$PHP_FOLDER\"", "r"));      
		$file_id++;
	}	
	$id_arr = (getFolderIdFromName($mysqli, $folderPathOrg, $username, $isAdmin)); //get last id of folder that match the username & name
	$fid = array_slice($id_arr, -1)[0];
	
	
	return ["fname"=>$folderPathOrg, "fid" => $fid];
	
}

