<?php
/*
 * Copyright 2005 - 2025 Centreon (https://www.centreon.com/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * For more information : contact@centreon.com
 *
 */

if (! isset($oreon)) {
    exit;
}

// Database retrieve information
$vmetric = [];

if (($o == METRIC_MODIFY || $o == METRIC_WATCH)
    && is_int($vmetricId)
) {
    $query = "SELECT *, hidden vhidden FROM virtual_metrics WHERE vmetric_id = {$vmetricId} LIMIT 1";
    $p_qy = $pearDB->query($query);
    // Set base value
    $vmetric = array_map('myDecode', $p_qy->fetchRow());
    $p_qy->closeCursor();
}
/*
 * Database retrieve information and list the different elements we need on the page
 *
 * Existing Data Index List comes from DBO -> Store in $indds Array
 */
$indds = ['' => sprintf('%s%s', _('Host list'), '&nbsp;&nbsp;&nbsp;')];
$mx_l = strlen($indds['']);

try {
    $dbindd = $pearDBO->query('SELECT DISTINCT 1 AS REALTIME, host_id, host_name FROM index_data;');
} catch (PDOException $e) {
    echo 'DB Error : ' . $e->getMessage() . '<br />';
}
while ($indd = $dbindd->fetchRow()) {
    $indds[$indd['host_id']] = $indd['host_name'] . '&nbsp;&nbsp;&nbsp;';
    $hn_l = strlen($indd['host_name']);
    if ($hn_l > $mx_l) {
        $mx_l = $hn_l;
    }
}
$dbindd->closeCursor();

// End of "database-retrieved" information

// Var information to format the element

$attrsText = ['size' => '30'];
$attrsText2 = ['size' => '10'];
$attrsAdvSelect = ['style' => 'width: 200px; height: 100px;'];
$attrsTextarea = ['rows' => '4', 'cols' => '60'];

$availableRoute = './api/internal.php?object=centreon_configuration_service&action=list';

$attrServices = ['datasourceOrigin' => 'ajax', 'availableDatasetRoute' => $availableRoute, 'linkedObject' => 'centreonService', 'multiple' => false];

if ($o !== METRIC_ADD) {
    $defaultRoute = './api/internal.php?object=centreon_configuration_graphvirtualmetric'
        . '&action=defaultValues&target=graphVirtualMetric&field=host_id&id=' . $vmetricId;

    $attrServices['defaultDatasetRoute'] = $defaultRoute;
}

// Form begin
$form = new HTML_QuickFormCustom('Form', 'post', '?p=' . $p);
if ($o == METRIC_ADD) {
    $form->addElement('header', 'ftitle', _('Add a Virtual Metric'));
} elseif ($o == METRIC_MODIFY) {
    $form->addElement('header', 'ftitle', _('Modify a Virtual Metric'));
} elseif ($o == METRIC_WATCH) {
    $form->addElement('header', 'ftitle', _('View a Virtual Metric'));
}

/*
 * Basic information
 * Header
 */
$form->addElement('header', 'information', _('General Information'));
$form->addElement('header', 'function', _('RPN Function'));
$form->addElement('header', 'options', _('Options'));
// General Information
$form->addElement('text', 'vmetric_name', _('Metric Name'), $attrsText);
// $form->addElement('text', 'hs_relation', _("Host / Service Data Source"), $attrsText);
$form->addElement('static', 'hsr_text', _('Choose a service if you want a specific virtual metric for it.'));
$form->addElement('select2', 'host_id', _('Linked Host Services'), [], $attrServices);

$form->addElement(
    'select',
    'def_type',
    _('DEF Type'),
    [0 => 'CDEF&nbsp;&nbsp;&nbsp;', 1 => 'VDEF&nbsp;&nbsp;&nbsp;'],
    'onChange=manageVDEF();'
);
// RPN Function
$form->addElement('textarea', 'rpn_function', _('RPN (Reverse Polish Notation) Function'), $attrsTextarea);
$form->addElement(
    'static',
    'rpn_text',
    _('<br><i><b><font color="#B22222">Notes </font>:</b></i><br>- '
        . 'Do not mix metrics of different sources.<br>- '
        . 'Only aggregation functions work in VDEF rpn expressions.')
);
// $form->addElement('select', 'real_metrics', null, $rmetrics);
$form->addElement('text', 'unit_name', _('Metric Unit'), $attrsText2);
$form->addElement('text', 'warn', _('Warning Threshold'), $attrsText2);
$form->addRule('warn', _('Must be a number'), 'numeric');
$form->addElement('text', 'crit', _('Critical Threshold'), $attrsText2);
$form->addRule('crit', _('Must be a number'), 'numeric');
// Options
$form->addElement('checkbox', 'vhidden', _('Hidden Graph And Legend'), '', 'onChange=manageVDEF();');
$form->addElement('textarea', 'comment', _('Comments'), $attrsTextarea);

$form->addElement('hidden', 'vmetric_id');
$redirect = $form->addElement('hidden', 'o');
$redirect->setValue($o);

// Form Rules
$form->applyFilter('__ALL__', 'myTrim');
$form->addRule('vmetric_name', _('Compulsory Name'), 'required');
$form->addRule('rpn_function', _('Required Field'), 'required');
$form->addRule('host_id', _('Required service'), 'required');

$form->registerRule('existName', 'callback', 'hasVirtualNameNeverUsed');
$form->registerRule('RPNInfinityLoop', 'callback', '_TestRPNInfinityLoop');
$form->addRule(
    'vmetric_name',
    _('Name already in use for this Host/Service'),
    'existName',
    $vmetric['index_id'] ?? null
);
$form->addRule(
    'rpn_function',
    _("Can't Use This Virtual Metric '" . (isset($_POST['vmetric_name'])
            ? htmlentities($_POST['vmetric_name'], ENT_QUOTES, 'UTF-8')
            : '') . "' In This RPN Function"),
    'RPNInfinityLoop'
);

$form->setRequiredNote("<font style='color: red;'>*</font>" . _(' Required fields'));

// End of form definition

// Smarty template initialization
$tpl = SmartyBC::createSmartyTemplate($path);

if ($o == METRIC_WATCH) {
    // Just watch
    $form->addElement(
        'button',
        'change',
        _('Modify'),
        ['onClick' => "javascript:window.location.href='?p=" . $p . '&o=c&vmetric_id=' . $vmetricId . "'"]
    );
    $form->setDefaults($vmetric);
    $form->freeze();
} elseif ($o == METRIC_MODIFY) {
    // Modify
    $hostId = $vmetric['host_id'] ?? null;
    $subC = $form->addElement('submit', 'submitC', _('Save'), ['class' => 'btc bt_success']);
    $res = $form->addElement('reset', 'reset', _('Reset'), ['onClick' => "javascript:resetLists({$hostId},{$vmetric['index_id']});", 'class' => 'btc bt_default']);
    $form->setDefaults($vmetric);
} elseif ($o == METRIC_ADD) {
    // Add
    $subA = $form->addElement('submit', 'submitA', _('Save'), ['class' => 'btc bt_success']);
    $res = $form->addElement(
        'reset',
        'reset',
        _('Reset'),
        ['onClick' => 'javascript:resetLists(0,0)', 'class' => 'btc bt_default']
    );
}

if ($o == METRIC_MODIFY || $o == METRIC_ADD) {
    ?>
    <script type='text/javascript'>
        function insertValueQuery() {
            var e_txtarea = document.Form.rpn_function;
            var e_select = document.getElementById('sl_list_metrics');
            var sd_o = e_select.selectedIndex;
            if (sd_o != -1) {
                var chaineAj = '';
                chaineAj = e_select.options[sd_o].text;
                //chaineAj = chaineAj.substring(0, chaineAj.length - 3);
                chaineAj = chaineAj.replace(/\s(\[[CV]DEF\]|)\s*$/, "");

                if (document.selection) {
                    // IE support
                    e_txtarea.focus();
                    sel = document.selection.createRange();
                    sel.text = chaineAj;
                    document.Form.insert.focus();
                } else if (e_txtarea.selectionStart || e_txtarea.selectionStart == '0') {
                    // MOZILLA/NETSCAPE support
                    var pos_s = e_txtarea.selectionStart;
                    var pos_e = e_txtarea.selectionEnd;
                    var str_rpn = e_txtarea.value;
                    e_txtarea.value = str_rpn.substring(0, pos_s) + chaineAj + str_rpn.substring(pos_e, str_rpn.length);
                } else {
                    e_txtarea.value += chaineAj;
                }
            }
        }

        function manageVDEF() {
            var e_checkbox = document.Form.vhidden;
            var vdef_state = document.Form.def_type.value;
            if (vdef_state == 1) {
                e_checkbox.checked = true;
            }
        }
    </script>
    <?php
}
$tpl->assign('msg', ['changeL' => 'main.php?p=' . $p . '&o=c&vmetric_id=' . $vmetricId, 'changeT' => _('Modify')]);

$tpl->assign('sort1', _('Properties'));
$tpl->assign('sort2', _('Graphs'));
// prepare help texts
$helptext = '';
include_once 'help.php';
foreach ($help as $key => $text) {
    $helptext .= '<span style="display:none" id="help:' . $key . '">' . $text . '</span>' . "\n";
}
$tpl->assign('helptext', $helptext);

$valid = false;
if ($form->validate()) {
    $vmetricObj = $form->getElement('vmetric_id');
    if ($o == METRIC_ADD) {
        $vmetricId = insertVirtualMetricInDB();
        $vmetricObj->setValue($vmetricId);
        try {
            enableVirtualMetricInDB($vmetricId);
        } catch (Exception $e) {
            $error = $e->getMessage();
        }
    } elseif ($o == METRIC_MODIFY) {
        try {
            updateVirtualMetricInDB($vmetricObj->getValue());
        } catch (Exception $e) {
            $error = $e->getMessage();
        }
    }
    if (! isset($error)) {
        $o = METRIC_WATCH;
        $form->addElement(
            'button',
            'change',
            _('Modify'),
            ['onClick' => "javascript:window.location.href='?p={$p}&o=c&vmetric_id=" . $vmetricObj->getValue() . "'"]
        );
        $form->freeze();
        $valid = true;
    }
}
$action = $form->getSubmitValue('action');
if ($valid) {
    require_once 'listVirtualMetrics.php';
} else {
    if (isset($error)) {
        echo "<p style='text-align: center'><span class='msg'>{$error}</span></p>";
    }
    // Apply a template definition
    $renderer = new HTML_QuickForm_Renderer_ArraySmarty($tpl);
    $renderer->setRequiredTemplate('{$label}&nbsp;<font color="red" size="1">*</font>');
    $renderer->setErrorTemplate('<font color="red">{$error}</font><br />{$html}');
    $form->accept($renderer);
    $tpl->assign('form', $renderer->toArray());
    $tpl->assign('o', $o);
    $tpl->display('formVirtualMetrics.ihtml');
}
$vdef = 1; // Display VDEF too

if ($o == METRIC_MODIFY || $o == METRIC_WATCH) {
    $host_service_id = isset($_POST['host_id']) && $_POST['host_id'] != null
        ? $_POST['host_id']
        : $vmetric['host_id'];
} elseif ($o == METRIC_ADD) {
    $host_service_id = isset($_POST['host_id']) && $_POST['host_id'] != null
        ? $_POST['host_id']
        : 0;
}
?>
<script type="text/javascript">
    jQuery(function () {
        jQuery('#sl_list_metrics').centreonSelect2({
            select2: {
                ajax: {
                    url: './api/internal.php?object=centreon_metric&action=ListOfMetricsByService'
                },
                placeholder: "List of known metrics",
                containerCssClass: 'filter-select'
            },
            multiple: false,
            allowClear: true,
            additionnalFilters: {
                id: '#host_id',
            }
        });
        // disable/enable List of known metrics in function of Linked Host Services to avoid an error 400
        // tip to check if we display the form
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has("o")) {
            const divLinkedHostServices = document.querySelector('#host_id');
            const j_divLinkedHostServices = $('#host_id');
            const divListKnownMetrics = document.querySelector('#sl_list_metrics');
            const j_divListKnownMetrics = $('#sl_list_metrics');
            if (divLinkedHostServices.value === '') {
                divListKnownMetrics.disabled = true;
            }
            j_divLinkedHostServices.on("change", function (e) {
                e.stopPropagation();
                j_divListKnownMetrics.val(null).trigger("change");
                let hasService = divLinkedHostServices.value !== '';
                divListKnownMetrics.disabled = !hasService;
            });
        }
    });
</script>
