<?php
function getYSFReflectorVersion() {
	// returns creation-time of YSFReflector as version-number          ----------     **********     ----------
	$filename = YSFREFLECTORPATH."/YSFReflector";
	exec($filename." -v 2>&1", $output);
	if (!startsWith(substr($output[0],21,8),"20")) {
		return getYSFReflectorFileVersion();
	} else {
		return substr($output[0],21,8)." (compiled ".getYSFReflectorFileVersion().")";
	}
}

function getYSFReflectorFileVersion() {
	// returns creation-time of YSFReflector as version-number          ----------     **********     ----------
	$filename = YSFREFLECTORPATH."/YSFReflector";
	if (file_exists($filename)) {
		return date("d M Y", filectime($filename));
	}
}

function getGitVersion() {
	//                                                                  ----------     **********     ----------
    if (file_exists(".VA2VDC")) {
    //    exec("git rev-parse --short HEAD", $output);
        return '20260412-VA2';  // 'GitID #<a href="<https://github.com/dg9vh/YSFReflector-Dashboard/commit/'.$output>[0].'" target="_blank">'.$output[0].'</a>';
    } else {
        return '<a href="http://amiatous.ddns.net:8080/DlFiles/index.php" target="_blank">12-04-2026_VA2</a>';
    }
}

// ***************************************************************************************************************************************

function getYSFReflectorConfig() {
	// loads YSFReflector.ini into array for further use                ----------     **********     ----------
	$conf = array();
	if ($configs = fopen(YSFREFLECTORINIPATH."/".YSFREFLECTORINIFILENAME, 'r')) {
		while ($config = fgets($configs)) {
			array_push($conf, trim ( $config, " \t\n\r\0\x0B"));
		}
		fclose($configs);
	}
	return $conf;
}

function getConfigItem($section, $key, $configs) {
	// retrieves the corresponding config-entry within a [section]      ----------     **********     ----------
	$sectionpos = array_search("[" . $section . "]", $configs) + 1;
	$len = count($configs);
	while(startsWith($configs[$sectionpos],$key."=") === false && $sectionpos <= ($len) ) {
		if (startsWith($configs[$sectionpos],"[")) {
			return null;
		}
		$sectionpos++;
	}
	return substr($configs[$sectionpos], strlen($key) + 1);
}

//------------------------------------------------------------------------------------------------------------------------------------------

function getYSFReflectorLog() {
	// Open Logfile and copy loglines into LogLines-Array()             -----  a+  ou r -----     **********     ----------
	$logLines = array();
$filePathLog = YSFREFLECTORLOGPATH . "/" . YSFREFLECTORLOGPREFIX . "-" . date("Y-m-d") . ".log";
$logDir = YSFREFLECTORLOGPATH; 

	if (!is_dir($logDir)) {
	    mkdir($logDir, 0777, true);
	}
	if (!file_exists($filePathLog)) {
	    $handle = fopen($filePathLog, 'w');
	    fclose($handle);
	    chmod($filePathLog, 0664);
	    shell_exec("chown MMDVM:MMDVM " . escapeshellarg($filePathLog));
	}

	if ($log = fopen($filePathLog, 'r')) {
		while ($logLine = fgets($log)) {
			if (startsWith($logLine, "M:"))
				array_push($logLines, $logLine);
		}
		fclose($log);
	}
	return $logLines;
}


function listdir_by_date($path){
	//                                                                  ----------     **********     ----------
        $dir = opendir($path);
        $list = array();
        while($file = readdir($dir)){
            if ($file != '.' and $file != '..' and startsWith($file,YSFREFLECTORLOGPREFIX)){
                $ctime = filectime($path . "/" . $file) . ',' . $file;
                $list[$ctime] = $file;
            }
        }
        closedir($dir);
        krsort($list);
        return $list;
}

function getOldYSFReflectorLog() {
	//                                                                  ----------     **********     ----------
        $dir = YSFREFLECTORLOGPATH;
        $scannedLogs = 0;
        $oldlogLines = array();
        $dir_files = listdir_by_date($dir);
        foreach ($dir_files as $file) {
            $filepath = $dir."/".$file;
            if ( is_file( $filepath ) && substr( $filepath, -4 ) == '.log' ) {
                if ($log = fopen($filepath, 'r')) {
                        while ($oldlogLine = fgets($log)) {
                                if (startsWith($oldlogLine, "M:")){
                                        array_push($oldlogLines, $oldlogLine);
                                }
                        }
                        fclose($log);
                        $scannedLogs++;
                        if ( $scannedLogs > SHOWOLDMHEARD ) {
                                break;
                        }
                }
            }
        }
	return $oldlogLines;
}

function getShortYSFReflectorLog() {
	// Open Logfile and copy loglines into LogLines-Array()             ----------     **********     ----------
	$logPath = YSFREFLECTORLOGPATH."/".YSFREFLECTORLOGPREFIX."-".date("Y-m-d").".log";
	//$logLines = explode("\n", `tail -n100 $logPath`);
	$logLines = explode("\n", `egrep -h "Received|watchdog" $logPath | tail -1`);
	return $logLines;
}


// Parses lines of type Adding VA2VDC (IP:PORT)       -------------------------------------------   *****  ---------
function parseAddingLine($logLine) {
    if (preg_match('/Adding\s+([A-Z0-9\/]+)\s+\(([\d\.]+):(\d+)\)/', $logLine, $matches)) {
        return [
            'callsign' => $matches[1],
            'ip' => $matches[2],
            'port' => $matches[3],
            'counter' => null,
        ];
    }
    return false;
}


// Parses lines of type CALLSIGN : IP:PORT COUNTER    -------------------------------------------   *****  ---------
function parseGatewayLogLine($logLine) {
    if (strpos($logLine, ':') === false) return false;
    $parts = explode(':', $logLine, 2);
    if (count($parts) < 2) return false;
    preg_match('/([A-Z0-9\/]+)\s*$/', $parts[0], $m_callsign);

    $callsign = isset($m_callsign[1]) ? trim($m_callsign[1]) : '';
    $after_colon = trim($parts[1]);
    $chunks = preg_split('/\s+/', $after_colon);
    $ipport = isset($chunks[0]) ? $chunks[0] : '';
    $cnt = isset($chunks[1]) ? $chunks[1] : '';

    $ip_parts = explode(':', $ipport);
    $ip = isset($ip_parts[0]) ? $ip_parts[0] : '';
    $port = isset($ip_parts[1]) ? $ip_parts[1] : '';
    if (
        filter_var($ip, FILTER_VALIDATE_IP) !== false &&
        preg_match('/^\d+$/', $port)
    ) {
        return [
            'callsign' => $callsign,
            'ip' => $ip,
            'port' => $port,
            'counter' => $cnt
        ];
    }
    return false;
}

function getConnectedGateways($logLines) {
	//  Version qui fonctionne bien                                     ----------     **********     ----------
	$gateways = Array();
	foreach ($logLines as $logLine) {
		if(strpos($logLine,"YSFReflector")){
			$gateways = Array();
		}
		if(strpos($logLine,"Adding")) {
			$lineParts = explode(" ", $logLine);
			if (!array_search($gateways, $lineParts[4])) {
				array_push($gateways, Array('callsign'=>$lineParts[4],'timestamp'=>$lineParts[1]." ".substr($lineParts[2],0,8)));
			}
		}
		if(strpos($logLine,"Removing")) {
			$lineParts = explode(" ", $logLine);
			$pos = array_search($lineParts[4],array_column($gateways, 'callsign'));
			array_splice($gateways, $pos, 1);
		}
	}
	return $gateways;
}



//
// Combines both parsers and returns unique gateways   Nouvelle Version  NO Good -----------  Pas Bonne --------------------------------   *****  ---------
// function newgetLinkedGateways($logLines) {
//     $gateways = array();
//     foreach ($logLines as $logLine) {
//         $parsed = parseAddingLine($logLine);
//         if (!$parsed) {
//             $parsed = parseGatewayLogLine($logLine);
//         }
//         if ($parsed) {
//             $exists = false;
//             foreach ($gateways as $g) {
//                 if ($g['callsign'] === $parsed['callsign'] && $g['ip'] === $parsed['ip'] && $g['port'] === $parsed['port']) {
//                     $exists = true;
//                     break;
//                 }
//             }
//             if (!$exists) {
//                 $gateways[] = $parsed;
//             }
//         } else {
//             error_log("Log line non parsee: " . trim($logLine));
//         }
//     }
//     return $gateways;
// }
//
//                                                                          ----------     **********     ----------

//0000000000111111111122222222223333333333444444444455555555556666666666
//0123456789012345678901234567890123456789012345678901234567890123456789
//M: 2016-06-24 11:11:41.787 Currently linked repeaters/gateways:
//M: 2016-06-24 11:11:41.787     GATEWAY   : 217.82.212.214:42000 2/60
//M: 2016-06-24 11:11:41.787     DM0GER    : 217.251.59.165:42000 5/60

function getLinkedGateways($logLines) {
	$gateways = Array();
	for ($i = count($logLines) -1; $i>=0; $i--) {
	    if (isset($logLines[$i])) {
		$logLine = $logLines[$i]; // 2025-09-09 21:05:46:  (mod_fastcgi.c.443) FastCGI-stderr:PHP Warning:  Undefined arry key 138 in /var/www/html/include/functions.php on line 234
		
		if (strpos($logLine, "Starting YSFReflector") !== false) {
			return $gateways;
		}
		if (strpos($logLine, "No repeaters/gateways linked") !== false) {
			return $gateways;
		}
		if (strpos($logLine, "Currently linked repeaters/gateways") !== false) {
			for ($j = $i + 1; $j < count($logLines); $j++) {
			    if (isset($logLines[$j])) {
				$logLine = $logLines[$j];
				if (!startsWith(substr($logLine,27), "   ")) {
					return $gateways;
				} else {
					$timestamp = substr($logLine, 3, 19);
					$callsign = substr($logLine, 31, 10);
					//$ipport = substr($logLine,43);
					$ipport = substr($logLine,31);
					$key = searchForKey("ipport",$ipport, $gateways);
					if ($key === NULL) {
						array_push($gateways, Array('callsign'=>$callsign,'timestamp'=>$timestamp,'ipport'=>$ipport));
					}
				}	
			}
		}
	}
     }
  }
   return $gateways;
 }
//     ---------------------------------------------------------------------------------------------     **********     ----------

// 00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888
// 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
// M: 2016-06-24 11:11:41.787 Currently linked repeaters/gateways:
// M: 2016-06-24 11:11:41.787     GATEWAY   : 217.182.212.214:42000 2/60 2025-09-09 23:30:56
// M: 2016-06-24 11:11:41.787     DM0GER    : 217.251.59.165:42000 5/60
//    x          j                x           Y             z      j     j          j
//

function getHeardList($logLines) {
	//                                                                      ----------     **********     ----------
    $heardList = array();
    $dttxend = "";
    foreach ($logLines as $logLine) {
        if (strpos($logLine,"Data from") == false && strpos($logLine,"Received command") == false &&
            strpos($logLine,"blocked") == false && strpos($logLine,"Reload the Blacklist from File") == false &&
            strpos($logLine,"YSF server status enquiry from") == false) {
            $duration = "En Onde ( Tx )";
//            $timestamp = substr($logLine, 3, 19);
            $TimesTp = substr($logLine, 3, 19);
            $dttimestamp = new DateTime($TimesTp);

            if ($dttxend !== "") {
		$stamp1 = $dttimestamp->getTimestamp(); // $dttimestamp->diff($dttxend)->format("%m:%s")
		$stamp2 = $dttxend->getTimestamp();
		$duration = (abs($stamp1 - $stamp2)) + 1;
            }

            $callsign2 = substr($logLine, strpos($logLine,"from") + 5, strpos($logLine,"to") - strpos($logLine,"from") - 6);
            $callsign = trim($callsign2);
            $target = substr($logLine, strpos($logLine, " to ") + 4, strpos($logLine," at ") - strpos($logLine, " to ") - 3);
            $gateway = substr($logLine, strrpos($logLine," at ") + 4);
            if (strpos($gateway, "FICH") == true) {
                $gateway = substr($gateway, 0, strpos($gateway, "FICH"));
            }
            if (strlen($callsign) < 11) {
                array_push($heardList, array(convertTimezone($TimesTp), $callsign, $target, $gateway, $duration));
            }
            if(strpos($logLine,"end of") || strpos($logLine,"watchdog has expired") || strpos($logLine,"ended RF data") || strpos($logLine,"ended network")) {
                $txend = substr($logLine, 3, 19);
                $dttxend = new DateTime($txend);
            }
        }
    }
    return $heardList;
}

function getLastHeard($logLines) {
	//returns last heard list from log                                  ----------     **********     ----------
	$lastHeard = array();
	$heardCalls = array();
	$heardList = getHeardList($logLines);
	$counter = 0;
	foreach ($heardList as $listElem) {
		if(!(array_search($listElem[1], $heardCalls) > -1)) {
			array_push($heardCalls, $listElem[1]);
			array_push($lastHeard, $listElem);
			$counter++;
		}
	}
	return $lastHeard;
}

function getSize($filesize, $precision = 2) {
	//                                                                  ----------     **********     ----------
	$units = array('', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y');
	foreach ($units as $idUnit => $unit) {
		if ($filesize > 1024)
			$filesize /= 1024;
		else
			break;
	}
	return round($filesize, $precision).' '.$units[$idUnit].'B';
}

function formatDateFrenchGW3($date) {
//    $dmjt = new DateTime($date, new DateTimeZone('UTC'));
//    $dmjt = modify('-4 hours');

    $mois = [
        'January' => 'Janvier', 'February' => 'Février', 'March' => 'Mars', 
        'April' => 'Avril', 'May' => 'Mai', 'June' => 'Juin', 
        'July' => 'Juillet', 'August' => 'Août', 'September' => 'Septembre', 
        'October' => 'Octobre', 'November' => 'Novembre', 'December' => 'Décembre'
    ];
    $jours = [
        'Monday' => 'Lundi', 'Tuesday' => 'Mardi', 'Wednesday' => 'Mercredi', 'Thursday' => 'Jeudi', 'Friday' => 'Vendredi', 'Saturday' => 'Samedi', 'Sunday' => 'Dimanche'
];

    $dateFormatted = date('H:i l d F Y ', strtotime($date));
//    $dateFormatted = $dmjt->format('H:i l d F Y ');
    $dateFormatted = strtr($dateFormatted, $jours);
    $dateFormatted = strtr($dateFormatted, $mois);
    // Remplace le nom du mois anglais par le français
    return $dateFormatted;
}




function formatDateFrenchGW2($date) {
    $mois = [
        'January' => 'Janvier', 'February' => 'Février', 'March' => 'Mars', 
        'April' => 'Avril', 'May' => 'Mai', 'June' => 'Juin', 
        'July' => 'Juillet', 'August' => 'Août', 'September' => 'Septembre', 
        'October' => 'Octobre', 'November' => 'Novembre', 'December' => 'Décembre'
    ];
    $jours = [
        'Monday' => 'Lundi', 'Tuesday' => 'Mardi', 'Wednesday' => 'Mercredi', 'Thursday' => 'Jeudi', 'Friday' => 'Vendredi', 'Saturday' => 'Samedi', 'Sunday' => 'Dimanche'
];

    $dateFormatted = date('H:i l d F Y ', strtotime($date));
//    $dateFormatted = strtr($dateFormatted, $jours);
    $dateFormatted = strtr($dateFormatted, $mois);
    // Remplace le nom du mois anglais par le français
    return $dateFormatted;
}

function formatDateFrench($date) {
    $mois = [
        'January' => 'Janvier', 'February' => 'Février', 'March' => 'Mars', 
        'April' => 'Avril', 'May' => 'Mai', 'June' => 'Juin', 
        'July' => 'Juillet', 'August' => 'Août', 'September' => 'Septembre', 
        'October' => 'Octobre', 'November' => 'Novembre', 'December' => 'Décembre'
    ];
    $jours = [
        'Monday' => 'Lundi', 'Tuesday' => 'Mardi', 'Wednesday' => 'Mercredi', 'Thursday' => 'Jeudi', 'Friday' => 'Vendredi', 'Saturday' => 'Samedi', 'Sunday' => 'Dimanche'
];

    $dateTxt = date('H:i l d F Y ', strtotime($date));
    $dateTxt = strtr($dateTxt, $jours);
    $dateTxt = strtr($dateTxt, $mois);
    // Remplace le nom du mois anglais par le français
    $dateFr = strtr($date, $mois);
    return $dateTxt;
}

function formatDateFrench2($timestamp) {
    $mois = [
        'January' => 'Janvier', 'February' => 'Février', 'March' => 'Mars', 
        'April' => 'Avril', 'May' => 'Mai', 'June' => 'Juin', 
        'July' => 'Juillet', 'August' => 'Août', 'September' => 'Septembre', 
        'October' => 'Octobre', 'November' => 'Novembre', 'December' => 'Décembre'
    ];
    $date = date('d F Y', strtotime($timestamp));
    $heure = date('H:i:s', strtotime($timestamp));
    // Remplace le nom du mois anglais par le français
    $dateFr = strtr($date, $mois);
    return $dateFr . ' (' . $heure . ')';
}
// Exemple d'appel  echo formatDateFrench('2025-09-27 05:53:27'); // Donne : 27 Septembre 2025 (05:53:27)

function formatDateSeule($timestamp) {
    $mois = [
        'January' => 'Janvier', 'February' => 'Février', 'March' => 'Mars',
        'April' => 'Avril', 'May' => 'Mai', 'June' => 'Juin',
        'July' => 'Juillet', 'August' => 'Août', 'September' => 'Septembre',
        'October' => 'Octobre', 'November' => 'Novembre', 'December' => 'Décembre'
    ];
    $date = date('d F Y', strtotime($timestamp));
    $dateFr = strtr($date, $mois);
    return $dateFr;
}
// Exemple d'appel  echo formatDateSeule(convertTimezone($gateway['timestamp'])); // Donne : 27 Septembre 2025

function formatHeureSeule($timestamp) {
    return date('H:i:s', strtotime($timestamp));
}
// Exemple d'appel  echo formatHeureSeule(convertTimezone($gateway['timestamp'])); // Donne : (05:53:27)

?>
