#!/usr/bin/php
<?php

// Send email notifcation for license three months, two months, 6-2 weeks and 7-1 days prior.

// LOGIC:
// check for license expiration date.
// if expiration date is < 1 week or already expired
	//- if last notifcation was sent a day or more ago.
		//- send notification to admin
// elseif expiration date is between 1 to 4 weeks
	//- if last notifcation was sent a week or more ago.
		//- send notification to admin
// elseif expiration date is between 2 to 3 month
	//- if last notifcation was sent a month or more ago.
		//- send notification to admin

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

use ombutel\email;
use ombutel\locale;
use ombutel\settings;
use ombutel\utils;

$cache_file = '/var/lib/ombutel/licenses/notify_license_cache';
$quota_cache_file = '/var/lib/ombutel/licenses/notify_quota_cache';

// frequency of sending emails
function expire_freq($valid_after, $valid_for) {
	$day = 86400;
	$week = 7 * $day;
	$month = 2628000;

	if($valid_for == 0) { return null; }

	$utc = new DateTimeZone('utc');
	$now = new DateTime('now', $utc);
	$expiration_date = new \DateTime('now', $utc);
	$expiration_date->setTimestamp($valid_after);
	$expiration_date = $expiration_date->add(new DateInterval("P{$valid_for}D")); // add valid_for

	if($expiration_date <= $now) {
		return $day; //expired
	}

	$diff = $expiration_date->diff($now);
	$diff_days = $diff->days;
	$diff_months = $diff->m;

	if(($diff_months == 3 && $diff->d == 0 && $diff->y == 0) ||
		($diff_months >= 1 && $diff_months < 3 && $diff->y == 0)
	) {
		return $month; // expires between 3 - 1 months
	} elseif($diff_days > 7 && $diff_months < 1 && $diff->y == 0) {
		return $week; // expires between 4 - 1 weeks
	} elseif($diff_days <= 7) {
		return $day; // expires in 7 - days or already expired
	}
	return null;
}

function last_mail_time($filename) {
	$last_email_time = @file_get_contents($filename);
	if(!$last_email_time) {
		$last_email_time = 0;
	}
	return $last_email_time;
}

function send_notification($from, $to, $subject, $body) {
	global $email_sent;
	$now = time();
	$system_name = __('cpbx.system_name', null, utils::system_name());
	$serial_number = __('cpbx.serial_number', null, utils::serial_number());
	$content = "<html><body>".
		"<p>{$body}</p>".
		"<p>{$system_name}</p>".
		"<p>{$serial_number}</p>".
		"<input type='hidden' value=\"{$now}\"/>". // prevent Gmail from hiding content
		"</body></html>";
	send_html_email($to, $subject, $content, null, $from, email::origin());
	$email_sent = true;
}

function send_license_grace_notification($from, $to, $license) {
	$subject = __('cpbx.licenses.admin.grace.subject', null, gethostname());
	$body = __('cpbx.licenses.admin.grace', null, $license->name, $license->grace_days);
	send_notification($from, $to, $subject, $body);
}

function send_license_invalid_notification($from, $to, $license) {
	$subject = __('cpbx.licenses.admin.invalid.subject', null, gethostname());
	$body = __('cpbx.licenses.admin.invalid', null, $license->name);
	send_notification($from, $to, $subject, $body);
}

function send_service_agreement_invalid_notification($from, $to, $license) {
	$subject = __('cpbx.service_agreement.expired.subject', null, utils::system_name());
	$body = __('cpbx.service_agreement.expired.body');
	send_notification($from, $to, $subject, $body);
}

function send_license_expiration_notification($from, $to, $license) {
	$subject = __('cpbx.licenses.admin.expire.subject', null, gethostname());
	$body = __('cpbx.licenses.admin.expire', null, $license->name);
	send_notification($from, $to, $subject, $body);
}

function get_quota_threshold($used_seconds, $limit_seconds) {
	if ($limit_seconds <= 0) {
		return null;
	}
	$percentage = ($used_seconds / $limit_seconds) * 100;
	if ($percentage >= 95) {
		return 95;
	} elseif ($percentage >= 90) {
		return 90;
	} elseif ($percentage >= 75) {
		return 75;
	}
	return null;
}

function get_last_quota_threshold($filename) {
	$data = @file_get_contents($filename);
	if (!$data) {
		return ['threshold' => 0, 'period' => ''];
	}
	$parts = explode('|', $data);
	return [
		'threshold' => intval($parts[0]),
		'period' => isset($parts[1]) ? $parts[1] : ''
	];
}

function send_quota_notification($from, $to, $threshold, $used_minutes, $limit_minutes, $license_name) {
	global $quota_email_sent;
	$used_hours = floor($used_minutes / 60);
	$used_mins = $used_minutes % 60;
	$limit_hours = floor($limit_minutes / 60);
	$limit_mins = $limit_minutes % 60;
	$used_formatted = number_format($used_hours) . sprintf(':%02d', $used_mins);
	$limit_formatted = number_format($limit_hours) . sprintf(':%02d', $limit_mins);

	$subject = __('cpbx.licenses.quota.subject', null, gethostname(), $license_name, $threshold);
	$body = __('cpbx.licenses.quota.body', null, $license_name, $threshold, $used_formatted, $limit_formatted);
	send_notification($from, $to, $subject, $body);
	$quota_email_sent = true;
}

function send_service_agreement_expiration_notification($from, $to, $license) {
	$valid_until = $license->valid_after + ($license->valid_for + 86400);
	$valid_until = new DateTime("@{$valid_until}", new DateTimeZone("UTC"));
	$subject = __('cpbx.service_agreement.expire.subject');
	$body = __('cpbx.service_agreement.expire.body', null,
		utils::system_name(),
		utils::serial_number(),
		$valid_until->format("F j, Y")
	);
	send_notification($from, $to, $subject, $body);
}

$licenses = function_exists('ombu_license_list') ? ombu_license_list() : [];
$from = settings::get('system_misc', 'fromemail');
$to = settings::get('system_misc', 'storageemail');
$last_email_time = last_mail_time($cache_file);
$now = time();
$email_sent = false;

if ($licenses && $to != '' && $now - $last_email_time >= 86400) {
	foreach ($licenses as $license) {
		if ($license->state == "grace") {
			if ($license->name != 'service-agreement') {
				send_license_grace_notification($from, $to, $license);
			}
		} else if ($license->state == "invalid") {
			if ($license->name == 'service-agreement') {
				send_service_agreement_invalid_notification($from, $to, $license);
			} else {
				send_license_invalid_notification($from, $to, $license);
			}
		} else {
			$period = expire_freq($license->valid_after, $license->valid_for);
			if (!is_null($period) && $now - $last_email_time >= $period) {
				if ($license->name == 'service-agreement') {
					send_service_agreement_expiration_notification($from, $to, $license);
				} else {
					send_license_expiration_notification($from, $to, $license);
				}
			}
		}
	}
}

if ($email_sent) {
	@mkdir(dirname($cache_file));
	@file_put_contents($cache_file, $now);
}

// Virtual Agent Quota Notifications
$quota_email_sent = false;
if ($to != '' && utils::has_virtual_agent_license()) {
	$quota_cache = get_last_quota_threshold($quota_cache_file);
	$current_period = date('Y-m');
	$last_quota_threshold = $quota_cache['threshold'];

	foreach (utils::$virtual_agent_license_names as $license_name) {
		$quota_status = utils::check_virtual_agent_quota($license_name);
		if ($quota_status['status'] == 'error' || $quota_status['limit_seconds'] <= 0) {
			continue;
		}

		// Reset threshold if new billing period (only for non-demo licenses)
		$is_demo = isset($quota_status['is_demo']) ? $quota_status['is_demo'] : false;
		if (!$is_demo && $quota_cache['period'] !== $current_period) {
			$last_quota_threshold = 0;
		}

		// Reset threshold if quota was refilled (usage dropped below cached threshold)
		$current_threshold_check = get_quota_threshold($quota_status['used_seconds'], $quota_status['limit_seconds']);
		if ($current_threshold_check === null || $current_threshold_check < $last_quota_threshold) {
			$last_quota_threshold = 0;
		}

		$license_description = isset($quota_status['license_description']) ? $quota_status['license_description'] : $license_name;
		$current_threshold = $current_threshold_check;
		if ($current_threshold !== null && $current_threshold > $last_quota_threshold) {
			send_quota_notification($from, $to, $current_threshold,
				$quota_status['used_minutes'], $quota_status['limit_minutes'], $license_description);
			$last_quota_threshold = $current_threshold;
		}
	}

	if ($quota_email_sent) {
		@mkdir(dirname($quota_cache_file));
		@file_put_contents($quota_cache_file, $last_quota_threshold . '|' . $current_period);
	}
}

?>
