<?php

/**
 * i-doit
 *
 * Abstract visualization view class.
 *
 * @package     modules
 * @subpackage  pro
 * @author      Leonard Fischer <lfischer@i-doit.com>
 * @version     1.0
 * @copyright   synetics GmbH
 * @license     http://www.i-doit.com/license
 * @since       i-doit 1.5.0
 */
abstract class isys_visualization
{
    /**
     * Variable which holds the database component.
     *
     * @var  isys_component_database
     */
    protected $m_db = null;

    /**
     * This array will hold the (filtered) object types for the frontend.
     *
     * @var  array
     */
    protected $m_object_types = [];

    /**
     * Options array which shall hold all necessary configuration.
     *
     * @var  array
     */
    protected $m_options = [];

    /**
     * Variable which holds the template component.
     *
     * @var  isys_component_template
     */
    protected $m_tpl = null;

    /**
     * This method will be called, if the current request is a AJAX request.
     *
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    abstract public function process();

    /**
     * Static method for retrieving the path, to the modules templates.
     *
     * @static
     * @global  array $g_dirs
     * @return  string
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public static function get_www_dir()
    {
        global $g_config;

        return $g_config['www_dir'] . 'src/classes/modules/pro/visualization/';
    }

    /**
     * Initializes the module.
     *
     * @param   array $p_options
     *
     * @return  $this
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function init(array $p_options = [])
    {
        return $this->set_options($p_options);
    }

    /**
     * Sets the options.
     *
     * @param   array $p_options
     *
     * @return  $this
     */
    public function set_options(array $p_options)
    {
        $this->m_options = $p_options;

        return $this;
    }

    /**
     * Sets a single option.
     *
     * @param   string $p_key
     * @param   mixed  $p_value
     *
     * @return  isys_visualization
     */
    public function set_option($p_key, $p_value)
    {
        $this->m_options[$p_key] = $p_value;

        return $this;
    }

    /**
     * Start method.
     *
     * @return  isys_visualization
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function start()
    {
        $language = isys_application::instance()->container->get('language');
        $routeGenerator = isys_application::instance()->container->get('route_generator');

        if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && substr($_GET['request'] ?? '', 0, 7) != 'mydoit_') {
            header('Content-Type: application/json');
            echo isys_format_json::encode([
                'success' => false,
                'data'    => null,
                'message' => 'This endpoint is deprecated!'
            ]);
            die;
        } else {
            // This is the default fallback for "visualization".
            $l_filters = [];

            // @see ID-4585  Only display object types that have objects (with status = normal).
            $dao = isys_cmdb_dao::instance($this->m_db);

            $subQuery = 'SELECT COUNT(*)
                FROM isys_obj
                WHERE isys_obj__isys_obj_type__id = isys_obj_type__id
                AND isys_obj__status = ' . $dao->convert_sql_int(C__RECORD_STATUS__NORMAL);

            $sql = 'SELECT *, (' . $subQuery . ') as objCount
                FROM isys_obj_type
                HAVING objCount > 0;';

            $result = $dao->retrieve($sql);

            while ($row = $result->get_row()) {
                $this->m_object_types[$row['isys_obj_type__id']] = [
                    'title'    => $language->get($row['isys_obj_type__title']),
                    'color'    => isys_helper_color::unifyHexColor((string)$row['isys_obj_type__color']),
                    'icon'     => $routeGenerator->generate('cmdb.object-type.icon', ['objectTypeId' => $row['isys_obj_type__id']]),
                    'filtered' => false
                ];
            }

            // Sorting by title, keeping the keys.
            uasort($this->m_object_types, function ($l_a, $l_b) {
                return strcasecmp($l_a['title'], $l_b['title']);
            });

            $l_service_filter = isys_itservice_dao_filter_config::instance($this->m_db)
                ->get_data();

            $l_filters[-1] = '-';

            // Collect the available it-service filters in a "dialog friendly" way.
            if (is_array($l_service_filter) && count($l_service_filter)) {
                foreach ($l_service_filter as $l_filter) {
                    $l_filters[$l_filter['isys_itservice_filter_config__id']] = $l_filter['isys_itservice_filter_config__title'];
                }
            }

            $l_rules = [
                'C_VISUALIZATION_SERVICE_FILTER' => [
                    'p_bInfoIconSpacer' => 0,
                    'p_arData'          => $l_filters,
                    'p_bDbFieldNN'      => true,
                    'p_strTitle'        => $language->get('LC__ITSERVICE__CONFIG'),
                    'p_strSelectedID'   => $_GET['service'],
                    'nowiki'            => true
                ]
            ];

            $this->m_tpl->activate_editmode()
                ->assign('ajax_url_visualization', isys_helper_link::create_url([C__GET__AJAX => 1, C__GET__AJAX_CALL => 'visualization']))
                ->assign('service_filter_url', isys_helper_link::create_url([C__GET__MODULE_ID => defined_or_default('C__MODULE__ITSERVICE'), C__GET__SETTINGS_PAGE => 'filter-config']))
                ->assign('visualization_www_dir', $this->get_www_dir())
                ->assign('visualization_dir', __DIR__)
                ->smarty_tom_add_rules('tom.content.top', $l_rules)
                ->include_template('leftcontent', __DIR__ . '/assets/visualization_left.tpl')
                ->include_template('contenttop', __DIR__ . '/assets/visualization_top.tpl');

            $this->process();
        }

        return $this;
    }

    /**
     * Visualization constructor.
     *
     * @param  isys_module_request $p_req
     */
    public function __construct(isys_module_request &$p_req)
    {
        $this->m_db = $p_req->get_database();
        $this->m_tpl = $p_req->get_template();
    }
}
