#!/usr/bin/php
<?php

require_once('/usr/share/ombutel/www/includes/cli.php');
require_once('send_email.php');

use ombutel\email;
use ombutel\settings;

try {
	if (email_sent_recently()) return;
	$email = settings::get('system_misc', 'storageemail');
	$from_mail = settings::get('system_misc', 'fromemail');
} catch (Exception $e) {
	fwrite(STDERR, "Could not load database check settings: {$e->getMessage()}\n");
	exit(1);
}

if ($email == '') return;

$issues = check_cdr_database(array_slice($argv, 1));
if ($issues) {
	$subject = _("Database table check failed at " . gethostname());
	$content = _("The following database table checks failed:\n\n") . implode("\n", $issues) . "\n";
	send_email($email, $subject, $content, null, $from_mail, null, null, null, null, email::origin());
	settings::set('system_misc', 'last_check_database', time());
}

function check_cdr_database($additional_tables = []) {
	$config = load_cdr_database_config();
	$issues = [];

	try {
		$pdo = new PDO(
			"mysql:host={$config['hostname']};dbname={$config['database']}",
			$config['username'],
			$config['password'],
			[ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]
		);
	} catch (Exception $e) {
		return [ _('Could not connect to the CDR/CEL database: ') . $e->getMessage() ];
	}

	$tables = [
		$config['database'] . "\0cdr" => [ $config['database'], 'cdr' ],
		$config['database'] . "\0cel" => [ $config['database'], 'cel' ]
	];
	foreach ($additional_tables as $argument) {
		if (!preg_match('/^([^.[:space:]]+)\.([^.[:space:]]+)$/', $argument, $match)) {
			$issues[] = sprintf(_("Invalid table argument '%s'; expected database.table"), $argument);
			continue;
		}
		$tables[$match[1] . "\0" . $match[2]] = [ $match[1], $match[2] ];
	}

	foreach ($tables as $table) {
		list($database, $table_name) = $table;
		try {
			$result = $pdo->query(sprintf(
				'check table `%s`.`%s` fast',
				str_replace('`', '``', $database),
				str_replace('`', '``', $table_name)
			));
			foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row) {
				if (!table_check_passed($row)) {
					$issues[] = sprintf('%s.%s: %s', $database, $table_name, $row['Msg_text']);
				}
			}
		} catch (Exception $e) {
			$issues[] = sprintf('%s.%s: %s', $database, $table_name, $e->getMessage());
		}
	}

	return $issues;
}

function table_check_passed($row) {
	return strtolower($row['Msg_type']) == 'status'
		&& in_array(strtolower($row['Msg_text']), [ 'ok', 'table is already up to date' ]);
}

function load_cdr_database_config() {
	$config = [
		'hostname' => 'localhost',
		'username' => 'asterisk',
		'password' => 'asterisk',
		'database' => 'asterisk'
	];
	$content = @file_get_contents('/etc/cpbx/apply_patches.conf') ?: '';
	if (preg_match_all('/^(\S+)[[:blank:]]*=[[:blank:]](\S+)/m', $content, $matches, PREG_SET_ORDER)) {
		foreach ($matches as $match) {
			switch ($match[1]) {
				case 'cdr_hostname': $config['hostname'] = trim($match[2]); break;
				case 'cdr_username': $config['username'] = trim($match[2]); break;
				case 'cdr_password': $config['password'] = trim($match[2]); break;
				case 'cdr_database': $config['database'] = trim($match[2]); break;
			}
		}
	}
	return $config;
}

function email_sent_recently() {
	return @intval(settings::get('system_misc', 'last_check_database')) + 86400 >= time();
}

?>
