<?php
ini_set('display_errors','0');
error_reporting(E_ALL);
session_start();
setlocale(LC_ALL, 'de_DE');

define('IN_COMATOR', true);
include('includes/function/database.php');
include('includes/function/helper.php');
include('dbopen.php');
$conn = database_connect($db);
if ($conn == NULL){
	http_response_code(500);
	header('Content-Type: application/json; charset=utf-8');
	print json_encode(array('success' => false, 'message' => 'Datenbankverbindung nicht möglich.'));
	exit;
}
include_once('includes/function/secure.php');
include_once('includes/function/modules_manager_update.php');

$stream = cmt_update_is_stream_request();
$expected = cmt_update_remote_token();
$given = isset($_SERVER['HTTP_X_COMATOR_TOKEN']) ? trim($_SERVER['HTTP_X_COMATOR_TOKEN']) : '';
if (!$expected || !$given || !hash_equals($expected, $given)){
	http_response_code(403);
	if ($stream){
		cmt_update_stream_prepare();
		cmt_update_stream_send('error', array('success' => false, 'message' => 'Forbidden'));
	} else {
		header('Content-Type: application/json; charset=utf-8');
		print json_encode(array('success' => false, 'message' => 'Forbidden'));
	}
	exit;
}

$action = isset($_POST['action']) ? preg_replace('/[^a-z_]/', '', $_POST['action']) : '';
$module_update = isset($_POST['module_update']) ? preg_replace('/[^a-zA-Z0-9_\-]/', '', $_POST['module_update']) : '';

if ($stream){
	if (session_status() === PHP_SESSION_ACTIVE) session_write_close();
	cmt_update_stream_prepare();

	if ($action != 'update' && $action != 'install' && $action != 'update_all'){
		cmt_update_stream_send('error', array('success' => false, 'message' => 'Ungültige Aktion.'));
		exit;
	}

	try {
		if ($action == 'update_all'){
			$updates = cmt_update_available_list(false);
			cmt_update_stream_send('start', array('success' => true, 'action' => 'update_all', 'total' => count($updates)));
			foreach ($updates AS $index => $item){
				$use_module = $item['module'];
				cmt_update_stream_send('module_start', array('module' => $use_module, 'action' => $item['action'], 'index' => $index + 1, 'total' => count($updates)));
				$result = cmt_update_execute($use_module, $item['action'], array(
					'remote' => true,
					'logger' => function($line) use ($use_module) {
						cmt_update_stream_send('log', array('module' => $use_module, 'message' => $line));
					},
					'progress' => function($phase, $percent) use ($use_module) {
						cmt_update_stream_send('progress', array(
							'module' => $use_module,
							'phase' => $phase,
							'percent' => (int)$percent
						));
					}
				));
				if (empty($result['success'])){
					cmt_update_stream_send('error', array('success' => false, 'module' => $use_module, 'message' => isset($result['message']) ? $result['message'] : 'Update fehlgeschlagen.'));
					exit;
				}
				cmt_update_stream_send('module_done', array('success' => true, 'module' => $use_module, 'index' => $index + 1, 'total' => count($updates)));
			}
			cmt_update_stream_send('done', array('success' => true, 'message' => 'Alle Updates abgeschlossen.'));
			exit;
		}

		if (!$module_update){
			cmt_update_stream_send('error', array('success' => false, 'message' => 'Kein Modul angegeben.'));
			exit;
		}

		cmt_update_stream_send('start', array('success' => true, 'module' => $module_update, 'action' => $action));
		$result = cmt_update_execute($module_update, $action, array(
			'remote' => true,
			'logger' => function($line) use ($module_update) {
				cmt_update_stream_send('log', array('module' => $module_update, 'message' => $line));
			},
			'progress' => function($phase, $percent) use ($module_update) {
				cmt_update_stream_send('progress', array(
					'module' => $module_update,
					'phase' => $phase,
					'percent' => (int)$percent
				));
			}
		));
		cmt_update_stream_send('done', array(
			'success' => !empty($result['success']),
			'module' => $module_update,
			'message' => isset($result['message']) ? $result['message'] : ''
		));
	} catch (Throwable $e) {
		cmt_update_stream_send('error', array('success' => false, 'module' => $module_update, 'message' => $e->getMessage()));
	}
	exit;
}

header('Content-Type: application/json; charset=utf-8');

if ($action == 'ping'){
	print json_encode(array('success' => true, 'message' => 'pong', 'domain' => $_SERVER['SERVER_NAME']), JSON_UNESCAPED_SLASHES);
	exit;
}
if ($action == 'list'){
	print json_encode(array('success' => true, 'updates' => cmt_update_available_list(false)), JSON_UNESCAPED_SLASHES);
	exit;
}
if ($action == 'update' || $action == 'install'){
	print json_encode(cmt_update_execute($module_update, $action, array('remote' => true)), JSON_UNESCAPED_SLASHES);
	exit;
}
if ($action == 'update_all'){
	$updates = cmt_update_available_list(false);
	$log = array();
	foreach ($updates AS $item){
		$result = cmt_update_execute($item['module'], $item['action'], array('remote' => true));
		if (isset($result['log'])) foreach ($result['log'] AS $line) $log[] = '['.$item['module'].'] '.$line;
		if (empty($result['success'])){
			print json_encode(array('success' => false, 'message' => $result['message'], 'log' => $log), JSON_UNESCAPED_SLASHES);
			exit;
		}
	}
	print json_encode(array('success' => true, 'message' => 'Alle Updates abgeschlossen.', 'log' => $log), JSON_UNESCAPED_SLASHES);
	exit;
}
print json_encode(array('success' => false, 'message' => 'Ungültige Aktion.'));
