<?php
/*
** Copyright (C) 2021-2026 initMAX s.r.o.
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** 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 Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/

/*
** GENERATED - do not edit by hand. This is Zabbix's widget-edit dialog view
** for 6.0/6.2, forked so it can render a MODULE widget's form, produced by
** the CI library's tools/legacy-widget-registry.php. Run the generator with
** --write instead of editing this file.
**
** WHY IT MUST BE IDENTICAL IN EVERY initMAX WIDGET: Zabbix registers one
** views/ directory per enabled module and resolves this view name to the
** FIRST module that ships it. With two initMAX widgets installed, one widget's
** copy answers for the other. When the copies differed (each carried its own
** widget's script registry), the losing widget's form opened with dead
** multiselects and colour pickers. One generic copy, the same bytes in every
** package, makes the load order irrelevant.
*/

/**
 * @var CView $this
 */
$output = [];
$root = Zbase::getRootDir();
$widget_view_file = $root.'/include/classes/widgets/views/widget.'.$data['dialogue']['type'].'.form.view.php';

// is_file does not use the include path, therefore absolute paths.
CView::registerDirectory($root.'/local/app/views');
CView::registerDirectory($root.'/app/views');
CView::registerDirectory($root.'/include/views');
$this->directory = $root.'/app/views';

if (version_compare(ZABBIX_VERSION, '6.2', '>=')) {
	$output['doc_url'] = CDocHelper::getUrl(CDocHelper::MONITORING_DASHBOARD_WIDGET_EDIT);
}

if (file_exists($widget_view_file)) {
	// A core widget: Zabbix's own form view, untouched.
	chdir(dirname($widget_view_file));
	$widget_view = include $widget_view_file;
}
else {
	$form = CWidgetHelper::createForm();
	$data['form'] = $form;
	$widget_view = ['form' => $form];

	/*
	 * A MODULE widget's form view is INCLUDED, not resolved through CView.
	 *
	 * CView validates the view NAME against /^[a-z]+(\/[a-z]+)*(\.[a-z]+)*$/ on
	 * 6.0 and 6.2 - lowercase letters only, no digits, no dash, no underscore -
	 * and a module widget's type is its manifest id, which this file does not
	 * get to choose. A widget whose id carries a dash or a capital could not be
	 * configured AT ALL on those two lines: the dialog sat on its spinner and
	 * the response was Zabbix's warning page, "Invalid view name".
	 *
	 * Including the file also hands back what the view RETURNS, so the scripts
	 * a form needs run after insertion travel the normal way. They are not
	 * optional: CWidgetHelper builds multiselects with `add_post_js => false`
	 * on the assumption that the dashboard view will emit their JS, and CView
	 * discards what an included view returns. Without them a picker renders as
	 * an EMPTY box with the right id already stored behind it - a widget that
	 * works and looks unconfigured.
	 *
	 * The file name is derived from the type the way CView would have accepted
	 * it: lowercased, with everything that is not a letter removed
	 * (gaugemax.form.view.php for type 'gaugemax').
	 *
	 * WHERE the module lives is read off the form class the cooperative widget
	 * registry (legacy/CWidgetConfig.<line>.php) already names - a class whose
	 * file is <module>/actions/widgets/<X>Form.php.
	 */
	$initmax_widgets = isset($GLOBALS['initmax_legacy_widgets'])
		? $GLOBALS['initmax_legacy_widgets']
		: [];
	$widget_type = $data['dialogue']['type'];
	$form_class = isset($initmax_widgets[$widget_type]['form_class'])
		? $initmax_widgets[$widget_type]['form_class']
		: null;
	$view_slug = preg_replace('/[^a-z]/', '', strtolower($widget_type));
	$module_form_view = null;
	$module_namespace = null;

	if ($form_class !== null && class_exists($form_class)) {
		$form_file = (new ReflectionClass($form_class))->getFileName();

		if (is_string($form_file)) {
			// <module>/actions/widgets/<X>Form.php -> <module>
			$module_dir = dirname($form_file, 3);
			$module_form_view = $module_dir.'/views/widgets/'.$view_slug.'.form.view.php';
		}

		// Modules\<NS>\Actions\Widgets\<X>Form -> Modules\<NS>
		if (preg_match('/^(Modules\\\\[^\\\\]+)\\\\/', $form_class, $ns_match)) {
			$module_namespace = $ns_match[1];
		}
	}

	if ($module_form_view !== null && is_file($module_form_view)) {
		$returned = include $module_form_view;

		if (is_array($returned)) {
			$widget_view = $returned + $widget_view;
		}
	}
	else {
		// Not an initMAX v1 widget, or a layout this fork does not know: the
		// original path, name regex and all.
		(new CView('widgets/'.$widget_type.'.form.view', $data))->getOutput();
	}

	/*
	 * Some forms cannot RETURN what they need: their view is rendered through a
	 * wrapper that discards the return value, so they register their scripts
	 * and jQuery templates on the module's own registry instead
	 * (Modules\<NS>\Includes\FormScripts). Drain it here, whichever shape it
	 * has - a plain list of scripts, or ['scripts' => [...], 'jq_templates' =>
	 * [...]] - so the form gets its initialisers no matter which module's copy
	 * of this view answered.
	 */
	$form_scripts_class = $module_namespace !== null ? $module_namespace.'\\Includes\\FormScripts' : null;

	if ($form_scripts_class !== null && class_exists($form_scripts_class)
			&& method_exists($form_scripts_class, 'take')) {
		$registered = $form_scripts_class::take();

		if (is_array($registered)) {
			$widget_view += ['scripts' => [], 'jq_templates' => []];

			if (array_key_exists('scripts', $registered) || array_key_exists('jq_templates', $registered)) {
				$widget_view['scripts'] = array_merge($widget_view['scripts'], $registered['scripts'] ?? []);
				$widget_view['jq_templates'] += ($registered['jq_templates'] ?? []);
			}
			else {
				$widget_view['scripts'] = array_merge($widget_view['scripts'], array_values($registered));
			}
		}
	}
}

$form = $widget_view['form']
	->addClass('dashboard-grid-widget-'.$data['dialogue']['type']);

// Submit button is needed to enable the submit event on Enter in inputs.
$form->addItem((new CInput('submit', 'dashboard_widget_config_submit'))->addStyle('display: none;'));

$output = [
	'header' => $data['unique_id'] !== null ? _s('Edit widget') : _s('Add widget'),
	'body' => '',
	'buttons' => [
		[
			'title' => $data['unique_id'] !== null ? _s('Apply') : _s('Add'),
			'class' => 'dialogue-widget-save',
			'keepOpen' => true,
			'isSubmit' => true,
			'action' => 'ZABBIX.Dashboard.applyWidgetProperties();'
		]
	],
	'data' => [
		'original_properties' => [
			'type' => $data['dialogue']['type'],
			'unique_id' => $data['unique_id'],
			'dashboard_page_unique_id' => $data['dashboard_page_unique_id']
		]
	]
] + $output;

$widget_view += ['scripts' => []];

if (version_compare(ZABBIX_VERSION, '6.2', '>=')) {
	$output['doc_url'] = CDocHelper::getUrl(CDocHelper::MONITORING_DASHBOARD_WIDGET_EDIT);

	// 6.2-specific dashboard initialisation javascript.
	$widget_view['scripts'][] = $this->readJsFile('monitoring.dashboard.widget.edit.js.php');
	$widget_view['scripts'][] = 'widget_form.init();';
}

if (($messages = getMessages()) !== null) {
	$output['body'] .= $messages->toString();
}

$output['body'] .= $form->toString();

if (array_key_exists('jq_templates', $widget_view)) {
	foreach ($widget_view['jq_templates'] as $id => $jq_template) {
		$output['body'] .= '<script type="text/x-jquery-tmpl" id="'.$id.'">'.$jq_template.'</script>';
	}
}

$output['body'] .= get_js(implode("\n", $widget_view['scripts']));

if ($data['user']['debug_mode'] == GROUP_DEBUG_MODE_ENABLED) {
	CProfiler::getInstance()->stop();
	$output['debug'] = CProfiler::getInstance()->make()->toString();
}

echo json_encode($output);
