<?php
/*
 * Copyright (c) 2003-2022 Willem Dijkstra
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * This class provides a convenient interface to rrdtool.
 */
require_once(__DIR__ . '/setup.inc');
require_once(__DIR__ . '/tools.inc');

class RRDTool {
    public string $method;
    public $cmdline;
    public $error;
    public $output;

    function __construct() {
        global $symon;

        $this->method = '';

        if (isset($symon['rrdtool_path'])) {
            if (!is_executable($symon['rrdtool_path'])) {
                config_error('rrdtool_path', 'is not an executable');
                return 0;
            }
        } else {
            config_error('rrdtool_path', 'is not set');
            return 0;
        }

        return 1;
    }

    function graph($filename, $args) {
        global $symon;

        $temp = is_array($args) ? $args : preg_split("/\n/", (string) $args);

        $args = [];
        reset($temp);
        foreach ($temp as $t) {
            if ($t == '') continue;
            if (preg_match("/^\s+$/s", (string) $t)) continue;
            $args[] = $t;
        }

        $cmdline = $symon['rrdtool_path'] . ' graph '. $filename .
                 hash2cmdline($args) . ' 2>&1';

        $result = $this->_exec($cmdline);

        if (isset($symon['rrdtool_debug'])) {
            $output = "\xa rrdtool graph debug output \xa cmdline: '$cmdline'\xa errors:'".$this->get_error()."'\xa output:'".$this->get_output()."'";
            error_log($output);
        }

        return $result;
    }

    function export($args) {
        global $symon;

        $temp = is_array($args) ? $args : preg_split("/\n/", (string) $args);

        $args = [];
        reset($temp);
        $step = "5";
        foreach ($temp as $t) {
            if ($t == '') continue;
            if (substr((string) $t, 0, 6) == '--step') {
                $step = substr((string) $t, 7);
                continue;
            }
            if (preg_match("/^\s+$/s", (string) $t)) continue;

            $args[] = $t;
        }

        $cmdline = $symon['rrdtool_path'] . ' xport --json --step '. $step . ' ' .
                 hash2cmdline($args) . ' 2>&1';

        $result = $this->_exec($cmdline, false);

        print $this->get_output();
        if (isset($symon['rrdtool_debug'])) {
            $output = "\xa rrdtool graph debug output \xa cmdline: '$cmdline'\xa errors:'".$this->get_error()."'\xa output:'".$this->get_output()."'";
            error_log($output);
        }

        return $result;
    }

    function get_error() {
        return $this->error;
    }

    function get_output() {
        return $this->output;
    }

    function _test() {
        global $symon;

        if ($this->exec('-v') == 0) {
            runtime_error('apache or php setup faulty: cannot execute '.$symon['rrdtool_path']);
            return 0;
        } else {
            $version_info = $this->get_output();
            if (strlen((string) $version_info) == 0) {
                runtime_error('apache or php setup faulty: can execute '.$symon['rrdtool_path']. ', but no results are returned');
                return 0;
            } else {
                print "\xa rrdtool version: ";
                if (preg_match("/rrdtool\s+(\S+)/i", (string) $version_info, $match)) {
                    print $match[1];
                } else {
                    print "unknown";
                }
                return 1;
            }
        }
    }

    function exec($cmdline) {
        global $symon;

        return $this->_exec($symon['rrdtool_path'] . ' ' . $cmdline);
    }

    function _exec($cmdline, $html=true) {
        global $runtime;

        $this->error = '';
        $this->output = '';
        $this->cmdline = $cmdline;

        unset($reta);
        exec($cmdline, $reta, $ret);

        if ($ret != 0) {
            foreach($reta as $key => $value) {
                $this->error .= '<pre>'.$value.'</pre><br>';
            }
            return 0;
        } else {
            foreach($reta as $value) {
                if ($value != "") {
                    if ($html) {
                        $this->output .= '<p>'.$value.'</p>';
                    } else {
                        $this->output .= $value;
                    }
                }
            }
            if (strstr($this->output, '<p>ERROR:')) {
                return 0;
            }
            return 1;
        }
        return 1;
    }
}
?>
