<?php
/*
** Zabbix
** Copyright (C) 2001-2018 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/


require_once dirname(__FILE__).'/include/config.inc.php';
require_once dirname(__FILE__).'/include/hosts.inc.php';
require_once dirname(__FILE__).'/include/triggers.inc.php';
require_once dirname(__FILE__).'/include/items.inc.php';

$page['title'] = _('Trigger');
$page['file'] = 'tr_logform.php';
$page['scripts'] = ['tr_logform.js'];
$page['type'] = detect_page_type(PAGE_TYPE_HTML);

define('ZBX_PAGE_NO_MENU', 1);

require_once dirname(__FILE__).'/include/page_header.php';

//		VAR			TYPE	OPTIONAL FLAGS	VALIDATION	EXCEPTION
$fields = [
	'description' =>	[T_ZBX_STR, O_OPT, null,		NOT_EMPTY,			'isset({add}) || isset({update})',
		_('Name')
	],
	'itemid' =>			[T_ZBX_INT, O_OPT, P_SYS,		DB_ID,				'isset({add}) || isset({update})'],
	'sform' =>			[T_ZBX_INT, O_OPT, null,		IN('0,1'),			null],
	'sitems' =>			[T_ZBX_INT, O_OPT, null,		IN('0,1'),			null],
	'triggerid' =>		[T_ZBX_INT, O_OPT, P_SYS,		DB_ID,				null],
	'type' =>			[T_ZBX_INT, O_OPT, null,		IN('0,1'),			null],
	'priority' =>		[T_ZBX_INT, O_OPT, null,		IN('0,1,2,3,4,5'),	'isset({add}) || isset({update})'],
	'expressions' =>	[T_ZBX_STR, O_OPT, null,		NOT_EMPTY,			'isset({add}) || isset({update})'],
	'expr_type' =>		[T_ZBX_INT, O_OPT, null,		IN('0,1'),			null],
	'comments' =>		[T_ZBX_STR, O_OPT, null,		null,				null],
	'url' =>			[T_ZBX_STR, O_OPT, null,		null,				null],
	'status' =>			[T_ZBX_INT, O_OPT, null,		IN([TRIGGER_STATUS_ENABLED, TRIGGER_STATUS_DISABLED]),	null],
	'form_refresh' =>	[T_ZBX_INT, O_OPT, null,		null,				null],
	// actions
	'add' =>			[T_ZBX_STR, O_OPT, P_SYS|P_ACT,	null,				null],
	'update' =>			[T_ZBX_STR, O_OPT, P_SYS|P_ACT,	null,				null],
	'keys' => 			[T_ZBX_STR, O_OPT, null,		null,				null],
];
check_fields($fields);

/*
 * Permissions
 */
if (getRequest('itemid')) {
	$items = API::Item()->get([
		'output' => [],
		'itemids' => getRequest('itemid'),
		'editable' => true
	]);

	if (!$items) {
		access_deny();
	}
}

if (getRequest('triggerid')) {
	$triggers = API::Trigger()->get([
		'output' => [],
		'triggerids' => getRequest('triggerid'),
		'editable' => true
	]);

	if (!$triggers) {
		access_deny();
	}
}

$itemid = getRequest('itemid', 0);

$constructor = new CTextTriggerConstructor(new CTriggerExpression());

/**
 * Save a trigger
 */
if (hasRequest('add') || hasRequest('update')) {
	$item = API::Item()->get([
		'output' => ['key_'],
		'selectHosts' => ['host'],
		'itemids' => $itemid,
		'limit' => 1
	]);
	$item = reset($item);
	$host = reset($item['hosts']);

	show_messages();

	$exprs = getRequest('expressions', false);
	if ($exprs && ($expression = $constructor->getExpressionFromParts($host['host'], $item['key_'], $exprs))) {
		if (!check_right_on_trigger_by_expression(PERM_READ_WRITE, $expression)) {
			access_deny();
		}

		$now = time();
		$status = hasRequest('status') ? TRIGGER_STATUS_ENABLED : TRIGGER_STATUS_DISABLED;
		$type = TRIGGER_MULT_EVENT_ENABLED;

		if (hasRequest('triggerid')) {
			$triggerId = getRequest('triggerid');
			$description = getRequest('description', '');

			$db_triggers = API::Trigger()->get([
				'output' => ['description', 'expression', 'templateid'],
				'triggerids' => [$triggerId]
			]);

			if ($db_triggers[0]['templateid'] != 0) {
				$db_triggers = CMacrosResolverHelper::resolveTriggerExpressions($db_triggers);

				$description = $db_triggers[0]['description'];
				$expression = $db_triggers[0]['expression'];
			}

			$trigger = [];
			$trigger['triggerid'] = $triggerId;
			$trigger['expression'] = $expression;
			$trigger['description'] = $description;
			$trigger['type'] = $type;
			$trigger['priority'] = getRequest('priority', 0);
			$trigger['status'] = $status;
			$trigger['comments'] = getRequest('comments', '');
			$trigger['url'] = getRequest('url', '');

			$result = (bool) API::Trigger()->update($trigger);

			$auditAction = AUDIT_ACTION_UPDATE;

			show_messages($result, _('Trigger updated'), _('Cannot update trigger'));
		}
		else {
			$trigger = [];
			$trigger['expression'] = $expression;
			$trigger['description'] = getRequest('description');
			$trigger['type'] = $type;
			$trigger['priority'] = getRequest('priority', 0);
			$trigger['status'] = $status;
			$trigger['comments'] = getRequest('comments', '');
			$trigger['url'] = getRequest('url', '');

			$result = (bool) API::Trigger()->create($trigger);
			if ($result) {
				$dbTriggers = API::Trigger()->get([
					'triggerids' => $result['triggerids'],
					'output' => ['triggerid']
				]);

				$dbTrigger = reset($dbTriggers);
				$triggerId = $dbTrigger['triggerid'];
			}

			$auditAction = AUDIT_ACTION_ADD;

			show_messages($result, _('Trigger added'), _('Cannot add trigger'));
		}

		if ($result) {
			DBstart();

			add_audit($auditAction, AUDIT_RESOURCE_TRIGGER,
				_('Trigger').' ['.$triggerId.'] ['.$trigger['description'].']'
			);

			DBend(true);

			unset($_REQUEST['sform']);

			zbx_add_post_js('closeForm("items.php");');
			require_once dirname(__FILE__).'/include/page_footer.php';
		}
	}
}

//------------------------ <FORM> ---------------------------

if (hasRequest('sform')) {
	if (hasRequest('triggerid') && !hasRequest('form_refresh')) {
		$result = DBselect(
			'SELECT t.expression,t.description,t.priority,t.comments,t.url,t.status,t.type'.
			' FROM triggers t'.
			' WHERE t.triggerid='.zbx_dbstr(getRequest('triggerid')).
				' AND EXISTS ('.
					'SELECT NULL'.
					' FROM functions f,items i'.
					' WHERE t.triggerid=f.triggerid'.
						' AND f.itemid=i.itemid '.
						' AND i.value_type IN ('.
							ITEM_VALUE_TYPE_LOG.','.ITEM_VALUE_TYPE_TEXT.','.ITEM_VALUE_TYPE_STR.
						')'.
				')'
		);

		if ($row = DBfetch($result)) {
			$description = $row['description'];
			$expression = CMacrosResolverHelper::resolveTriggerExpression($row['expression']);
			$type = $row['type'];
			$priority = $row['priority'];
			$comments = $row['comments'];
			$url = $row['url'];
			$status = $row['status'];
		}

		// break expression into parts
		$expressions = $constructor->getPartsFromExpression($expression);
	}
	else {
		$description = getRequest('description', '');
		$expressions = getRequest('expressions', []);
		$type = getRequest('type', 0);
		$priority = getRequest('priority', 0);
		$comments = getRequest('comments', '');
		$url = getRequest('url', '');

		if (!hasRequest('form_refresh')) {
			$status = TRIGGER_STATUS_ENABLED;
		}
		else {
			$status = hasRequest('status') ? TRIGGER_STATUS_ENABLED : TRIGGER_STATUS_DISABLED;
		}
	}

	$keys = getRequest('keys', []);

	$items = API::Item()->get([
		'output' => ['itemid', 'hostid', 'key_', 'name'],
		'selectHosts' => ['name'],
		'itemids' => [$itemid]
	]);

	if ($items) {
		$items = CMacrosResolverHelper::resolveItemNames($items);
		$item_name = $items[0]['hosts'][0]['name'].NAME_DELIMITER.$items[0]['name_expanded'];
	}
	else {
		$item_name = '';
	}

	$form = (new CForm())
		->setName('sform')
		->addVar('sform', '1')
		->addVar('itemid', $itemid);

	if (hasRequest('triggerid')) {
		$form->addVar('triggerid', getRequest('triggerid'));
	}

	$key_table = (new CTable())
		->setId('key_list')
		->setAttribute('style', 'width: 100%;')
		->setHeader([_('Keyword'), _('Type'), _('Action')]);

	$max_id = 0;
	foreach ($keys as $id => $val) {
		$key_table->addRow(
			(new CRow([
				htmlspecialchars($val['value']),
				$val['type'],
				(new CCol(
					(new CButton(null, _('Remove')))
						->addClass(ZBX_STYLE_BTN_LINK)
						->onClick('javascript: remove_keyword("keytr'.$id.'");')
				))->addClass(ZBX_STYLE_NOWRAP)
			]))->setId('keytr'.$id)
		);

		$form
			->addVar('keys['.$id.'][value]', $val['value'])
			->addVar('keys['.$id.'][type]', $val['type']);

		$max_id = max($max_id, $id);
	}

	zbx_add_post_js('key_count='.($max_id + 1).';');

	$expression_table = (new CTable())
		->setId('exp_list')
		->setAttribute('style', 'width: 100%;')
		->setHeader([_('Expression'), _('Type'), _('Position'), _('Action')]);

	$max_id = 0;
	foreach ($expressions as $id => $expr) {
		$imgup = (new CImg('images/general/arrow_up.png', 'up', 12, 14))
			->onClick('javascript: element_up("logtr'.$id.'");')
			->onMouseover('javascript: this.style.cursor = "pointer";')
			->addClass('updown');

		$imgdn = (new CImg('images/general/arrow_down.png', 'down', 12, 14))
			->onClick('javascript: element_down("logtr'.$id.'");')
			->onMouseover('javascript: this.style.cursor = "pointer";')
			->addClass('updown');

		$expression_table->addRow(
			(new CRow([
				htmlspecialchars($expr['value']),
				($expr['type'] == CTextTriggerConstructor::EXPRESSION_TYPE_MATCH) ? _('Include') : _('Exclude'),
				[$imgup, ' ', $imgdn],
				(new CCol(
					(new CButton(null, _('Remove')))
						->addClass(ZBX_STYLE_BTN_LINK)
						->onClick('javascript: remove_expression("logtr'.$id.'");')
				))->addClass(ZBX_STYLE_NOWRAP)
			]))->setId('logtr'.$id)
		);

		$form
			->addVar('expressions['.$id.'][value]', $expr['value'])
			->addVar('expressions['.$id.'][type]', $expr['type']);

		$max_id = max($max_id, $id);
	}

	zbx_add_post_js('logexpr_count='.($max_id + 1).';');
	zbx_add_post_js('processExpressionList();');

	$form->addItem(
		(new CTabView())
			->addTab('trigger_tab', null,
				(new CFormList())
					->addRow(_('Name'),
						(new CTextBox('description', $description))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
					)
					->addRow(_('Item'), [
						(new CTextBox('item', $item_name))
							->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
							->setId('item')
							->setAttribute('disabled', 'disabled'),
						(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
						(new CButton(null, _('Select')))
							->addClass(ZBX_STYLE_BTN_GREY)
							->onClick("javascript: return PopUp('popup.php?dstfrm=".$form->getName().
								"&dstfld1=itemid&dstfld2=item&srctbl=items&srcfld1=itemid&srcfld2=name');"
							)
					])
					->addRow(_('Severity'), new CSeverity(['name' => 'priority', 'value' => (int) $priority]))
					->addRow(_('Expression'),
						(new CTextBox('expression'))
							->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
							->setId('logexpr')
					)
					->addRow(null, [
						(new CCheckBox('iregexp'))->setLabel('iregexp'),
						(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
						(new CButton('add_key_and', _('AND')))
							->addClass(ZBX_STYLE_BTN_GREY)
							->onClick('javascript: add_keyword_and();'),
						(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
						(new CButton('add_key_or', _('OR')))
							->addClass(ZBX_STYLE_BTN_GREY)
							->onClick('javascript: add_keyword_or();'),
						(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
						(new CComboBox('expr_type', null, null, [
							CTextTriggerConstructor::EXPRESSION_TYPE_MATCH => _('Include'),
							CTextTriggerConstructor::EXPRESSION_TYPE_NO_MATCH => _('Exclude')
						]))->setId('expr_type'),
						(new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN),
						(new CButton('add_exp', _('Add')))
							->addClass(ZBX_STYLE_BTN_GREY)
							->onClick('javascript: add_logexpr();')
					])
					->addRow(null,
						(new CDiv($key_table))
							->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
							->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
					)
					->addRow(null,
						(new CDiv($expression_table))
							->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR)
							->setAttribute('style', 'min-width: '.ZBX_TEXTAREA_BIG_WIDTH.'px;')
					)
					->addRow(_('URL'), (new CTextBox('url', $url))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH))
					->addRow(_('Description'),
						(new CTextArea('comments', $comments))->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH)
					)
					->addRow(_('Enabled'), (new CCheckBox('status'))->setChecked($status == TRIGGER_STATUS_ENABLED))
			)
			->setFooter(makeFormFooter(
				(hasRequest('triggerid') ? new CSubmit('update', _('Update')) : new CSubmit('add', _('Add'))),
				[(new CButton('cancel', _('Cancel')))->onClick('javascript: self.close();')]
			))
	);

	(new CWidget())
		->setTitle(_('Trigger'))
		->addItem($form)
		->show();
}

require_once dirname(__FILE__).'/include/page_footer.php';
