<?php
namespace App\Cron\Job;

/**
 * Cleanp auto process logs
 * @author Laura Motoc
 *
 * Deletes data from auto process
 * It should run once per week or per month, outside working hours
 *
 * @see DatabaseCleanupForErrorLogs
 */
class DatabaseCleanupForAutoProcessLogs extends \App\Cron\Job\Utils\ShortRunningCronJobAbstract
{
	/**
	 * Cronjob category: {system|operational|financial|reporting}
	 * @var string
	 */
	protected $category = 'system';


	/**
	 * Script/DB stats
	 * @var array
	 */
	protected $stats = [];

	protected $defaultSettings = [
		'logsPeriod'	=> 		'6m',
	];


	private $cache = [];

	/**
	 * The method returns the form which is needed for the the current cronjob settings saving.
	 */
	public function getSettingsDialog(array $fields)
	{
		$form = parent::getSettingsDialog($fields);

		$_LANG = \App\Loader_Lang::getInstance()->getGlobal();
		$lang = \App\Loader_Lang::getInstance()->getSection("Admin/CronJobs/Management/DatabaseCleanupForAutoProcessLogs");

		$formContainer = \Engine\Form\Container\Fieldset::create($_LANG['Admin']['CronJobs']['Management']['formFields']['legend']);

		$form->addContainer($formContainer);

		$fld = new \Engine\Form\Input\Select($lang['options']['logsPeriod'], 'logsPeriod', $fields['settings']['logsPeriod'], [
			'1w' =>   	$lang['options']['logsPeriod_values_1w'],
			'2w' =>   	$lang['options']['logsPeriod_values_2w'],
			'1m' =>   	$lang['options']['logsPeriod_values_1m'],
			'2m' =>   	$lang['options']['logsPeriod_values_2m'],
			'3m' =>   	$lang['options']['logsPeriod_values_3m'],
			'4m' =>   	$lang['options']['logsPeriod_values_4m'],
			'5m' =>   	$lang['options']['logsPeriod_values_5m'],
			'6m' =>   	$lang['options']['logsPeriod_values_6m'],
			'9m' =>   	$lang['options']['logsPeriod_values_9m'],
			'1y' =>   	$lang['options']['logsPeriod_values_1y'],
		]);
		$fld->setTooltip($lang['options']['logsPeriodTooltip']);
		$formContainer->addElement($fld);

		$formContainer->groupInputsInArray("settings");

		return $form;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Cron\Job\Utils\GeneralAbstract::executeJob()
	 */
	protected function executeJob()
	{
		$this->cleanupOldErrorLogs();
	}

	protected function cleanupOldErrorLogs()
	{
		// compose & validate input data
		$minAddTime = null;
		switch ($this->settings['logsPeriod']) {
			case '1w':
				$minAddTime = \Engine\DateTime::create()->modify("-1week");
			break;
			case '2w':
				$minAddTime = \Engine\DateTime::create()->modify("-2weeks");
			break;
			case '1m':
				$minAddTime = \Engine\DateTime::create()->modify("-1months");
			break;
			case '2m':
				$minAddTime = \Engine\DateTime::create()->modify("-2months");
			break;
			case '3m':
				$minAddTime = \Engine\DateTime::create()->modify("-3months");
			break;
			case '4m':
				$minAddTime = \Engine\DateTime::create()->modify("-4months");
			break;
			case '5m':
				$minAddTime = \Engine\DateTime::create()->modify("-5months");
			break;
			case '6m':
				$minAddTime = \Engine\DateTime::create()->modify("-6months");
			break;
			case '9m':
				$minAddTime = \Engine\DateTime::create()->modify("-9months");
			break;
			case '1y':
				$minAddTime = \Engine\DateTime::create()->modify("-1years");
			break;

			default:
				throw new \Exception("Unknown logsPeriod value: {$this->settings['logsPeriod']}");
		}

		// get records count
		global $DBTAutoProcessLogs;
		$db = \DB::getInstance();

		$errorLogsCount = $db->GetOne("SELECT COUNT(*) FROM `{$DBTAutoProcessLogs}`");
		if ($db->ErrorNo()) {
			throw new \DBException(sprintf("[%s] Cannot get records count. Error: %s", __METHOD__, $db->ErrorMsg()));
		}

		$errorLogsMinAddTime = $db->GetOne("SELECT MIN(`addTime`) FROM `{$DBTAutoProcessLogs}`");
		if ($db->ErrorNo()) {
			throw new \DBException(sprintf("[%s] Cannot select data. Error: %s", __METHOD__, $db->ErrorMsg()));
		}

		$errorLogsMinId = $db->GetOne("SELECT MIN(`id`) FROM `{$DBTAutoProcessLogs}`");
		if ($db->ErrorNo()) {
			throw new \DBException(sprintf("[%s] Cannot select data. Error: %s", __METHOD__, $db->ErrorMsg()));
		}

		$this->logger->info(sprintf("The autoProcess_logs table contains %s records. First record is from %s (id: %s)", $errorLogsCount, \Engine\DateTime::createFromTimestamp($errorLogsMinAddTime)->formatDateTimeIso(), $errorLogsMinId));

		$this->logger->info(sprintf("We should delete records before %s", $minAddTime->formatDateTimeIso()));

		if ($errorLogsMinAddTime<$minAddTime->formatTime()) {
			$db->Execute("DELETE FROM `{$DBTAutoProcessLogs}` WHERE `addTime`<?", [$minAddTime->getTimestamp(), ]);
			if ($db->ErrorNo()) {
				throw new \DBException(sprintf("[%s] Cannot delete records. Error: %s", __METHOD__, $db->ErrorMsg()));
			}

			$deletedRecords = $db->Affected_Rows();
			$this->logger->success(sprintf("Deleted %s records", $deletedRecords));
		}
		else {
			$this->logger->idle(sprintf("There is nothing to delete in that interval"));
		}
	}
}