<?php

/**
 * i-doit
 *
 * DAO: global category for Check_MK.
 *
 * @package     Modules
 * @subpackage  Check_MK
 * @author      Leonard Fischer <lfischer@i-doit.com>
 * @version     1.0.0
 * @copyright   synetics GmbH
 * @license     http://www.i-doit.com/license
 * @since       i-doit 1.4.0
 */
class isys_cmdb_dao_category_g_cmk_tag extends isys_cmdb_dao_category_global
{
    /**
     * Category's name. Will be used for the identifier, constant, main table, and many more.
     *
     * @var  string
     */
    protected $m_category = 'cmk_tag';

    /**
     * Category entry is purgable
     *
     * @var  boolean
     */
    protected $m_is_purgable = true;

    /**
     * Callback method for property host.
     *
     * @param   isys_request $p_request
     *
     * @return  string
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function callback_property_tags(isys_request $p_request)
    {
        global $g_comp_database;

        return isys_cmdb_dao_category_g_cmk_tag::instance($g_comp_database)
            ->get_tags_for_dialog_list($p_request->get_object_id());
    }

    /**
     * Creates new entity.
     *
     * @param   array $p_data
     *
     * @return  mixed
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function create_data($p_data)
    {
        if (isset($p_data['tags']) && !isys_format_json::is_json_array($p_data['tags'])) {
            if (strpos($p_data['tags'], ',') !== false) {
                $p_data['tags'] = explode(',', $p_data['tags']);
            }

            $p_data['tags'] = (array) $p_data['tags'];

            $p_data['tags'] = isys_format_json::encode(array_filter(array_map('intval', $p_data['tags'])));
        }

        return parent::create_data($p_data);
    }

    /**
     * Get data method.
     *
     * @param   integer $p_category_data_id
     * @param   mixed   $p_obj_id
     * @param   string  $p_condition
     * @param   mixed   $p_filter
     * @param   integer $p_status
     *
     * @return  isys_component_dao_result
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function get_data($p_category_data_id = null, $p_obj_id = null, $p_condition = '', $p_filter = null, $p_status = null)
    {
        $l_sql = 'SELECT * FROM isys_catg_cmk_tag_list
			LEFT JOIN isys_obj ON isys_obj__id = isys_catg_cmk_tag_list__isys_obj__id
			LEFT JOIN isys_obj_type ON isys_obj_type__id = isys_obj__isys_obj_type__id
			LEFT JOIN isys_catg_cmk_list ON isys_catg_cmk_tag_list__isys_obj__id = isys_catg_cmk_list__isys_obj__id
			WHERE TRUE ' . $p_condition . ' ' . $this->prepare_filter($p_filter) . ' ';

        if ($p_obj_id !== null) {
            $l_sql .= $this->get_object_condition($p_obj_id);
        }

        if ($p_category_data_id !== null) {
            $l_sql .= " AND isys_catg_cmk_tag_list__id = " . $this->convert_sql_id($p_category_data_id);
        }

        if ($p_status !== null) {
            $l_sql .= " AND isys_catg_cmk_tag_list__status = " . $this->convert_sql_int($p_status);
        }

        return $this->retrieve($l_sql . ';');
    }

    /**
     * Method for returning the properties.
     *
     * @return  array
     * @throws  Exception
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    protected function properties()
    {
        return [
            'tags'         => array_replace_recursive(isys_cmdb_dao_category_pattern::dialog_list(), [
                C__PROPERTY__INFO     => [
                    C__PROPERTY__INFO__TITLE       => 'LC__CATG__CMK_TAG__TAGS',
                    C__PROPERTY__INFO__DESCRIPTION => 'Tags'
                ],
                C__PROPERTY__DATA     => [
                    C__PROPERTY__DATA__FIELD => 'isys_catg_cmk_tag_list__tags',
                    C__PROPERTY__DATA__TYPE  => C__TYPE__TEXT
                ],
                C__PROPERTY__FORMAT   => [
                    C__PROPERTY__FORMAT__CALLBACK => ['isys_global_cmk_tag_export_helper', 'tags']
                ],
                C__PROPERTY__UI       => [
                    C__PROPERTY__UI__ID     => 'C__CATG__CMK_TAG__TAGS',
                    C__PROPERTY__UI__PARAMS => [
                        'p_arData' => new isys_callback(['isys_cmdb_dao_category_g_cmk_tag', 'callback_property_tags'])
                    ]
                ],
                C__PROPERTY__PROVIDES => [
                    C__PROPERTY__PROVIDES__SEARCH     => false,
                    C__PROPERTY__PROVIDES__REPORT     => false,
                    C__PROPERTY__PROVIDES__MULTIEDIT  => false,
                    C__PROPERTY__PROVIDES__LIST       => false,
                    C__PROPERTY__PROVIDES__VALIDATION => false
                ]
            ]),
            'cmdb_tags'    => array_replace_recursive(isys_cmdb_dao_category_pattern::virtual(), [
                C__PROPERTY__INFO     => [
                    C__PROPERTY__INFO__TITLE       => 'LC__CATG__CMK_TAG__CMDB_TAGS',
                    C__PROPERTY__INFO__DESCRIPTION => 'CMDB tags'
                ],
                C__PROPERTY__DATA     => [
                    C__PROPERTY__DATA__FIELD => 'isys_catg_cmk_tag_list__id'
                ],
                C__PROPERTY__FORMAT   => [
                    C__PROPERTY__FORMAT__CALLBACK => ['isys_global_cmk_tag_export_helper', 'cmdbTags']
                ],
                C__PROPERTY__PROVIDES => [
                    C__PROPERTY__PROVIDES__VALIDATION => false
                ]
            ]),
            'dynamic_tags' => array_replace_recursive(isys_cmdb_dao_category_pattern::virtual(), [
                C__PROPERTY__INFO     => [
                    C__PROPERTY__INFO__TITLE       => 'LC__CATG__CMK_TAG__DYNAMIC_TAGS',
                    C__PROPERTY__INFO__DESCRIPTION => 'Dynamic tags'
                ],
                C__PROPERTY__DATA     => [
                    C__PROPERTY__DATA__FIELD => 'isys_catg_cmk_tag_list__id'
                ],
                C__PROPERTY__FORMAT   => [
                    C__PROPERTY__FORMAT__CALLBACK => ['isys_global_cmk_tag_export_helper', 'dynamicTags']
                ],
                C__PROPERTY__PROVIDES => [
                    C__PROPERTY__PROVIDES__VALIDATION => false
                ]
            ]),
            'description'  => array_replace_recursive(isys_cmdb_dao_category_pattern::commentary(), [
                C__PROPERTY__INFO => [
                    C__PROPERTY__INFO__TITLE       => 'LC__CMDB__LOGBOOK__DESCRIPTION',
                    C__PROPERTY__INFO__DESCRIPTION => 'Description'
                ],
                C__PROPERTY__DATA => [
                    C__PROPERTY__DATA__FIELD => 'isys_catg_cmk_tag_list__description'
                ],
                C__PROPERTY__UI   => [
                    C__PROPERTY__UI__ID => 'C__CMDB__CAT__COMMENTARY_' . C__CMDB__CATEGORY__TYPE_GLOBAL . C__CATG__CMK_TAG
                ]
            ])
        ];
    }

    /**
     * Dynamic property callback for CMDB tags.
     *
     * @param  integer $categoryEntryId
     * @param  array   $row
     *
     * @return array
     */
    public function dynamic_property_callback_static_tags($categoryEntryId, $row)
    {
        if (isys_format_json::is_json_array($row['isys_catg_cmk_tag_list__tags'])) {
            $tags = isys_format_json::decode($row['isys_catg_cmk_tag_list__tags']);

            if (count($tags)) {
                foreach ($tags as &$tag) {
                    $tagData = isys_factory_cmdb_dialog_dao::get_instance('isys_check_mk_tags', $this->m_db)->get_data($tag);
                    $tagGroup = null;

                    if ($tagData['isys_check_mk_tags__isys_check_mk_tag_groups__id'] > 0) {
                        $tagGroupData = isys_factory_cmdb_dialog_dao::get_instance('isys_check_mk_tag_groups', $this->m_db)->get_data($tagData['isys_check_mk_tags__isys_check_mk_tag_groups__id']);

                        $tagGroup = isys_check_mk_helper_tag::prepare_valid_tag_name($tagGroupData['title']);
                    }

                    $tag = [
                        'id'    => $tag,
                        'const' => isys_check_mk_helper_tag::prepare_valid_tag_name($tagData['isys_check_mk_tags__unique_name']),
                        'val'   => $tagData['isys_check_mk_tags__display_name'],
                        'sel'   => true,
                        'group' => $tagGroup
                    ];
                }

                return $tags;
            }
        }

        return [];
    }

    /**
     * Dynamic property callback for CMDB tags.
     *
     * @param  integer $categoryEntryId
     * @param  array   $row
     *
     * @return array
     * @throws isys_exception_database
     */
    public function dynamic_property_callback_cmdb_tags($categoryEntryId, $row)
    {
        $return = [];

        if (class_exists('isys_check_mk_helper_tag')) {
            $propertyDao = isys_cmdb_dao_category_property::instance($this->m_db);
            $tags = isys_check_mk_helper_tag::factory($row['isys_obj_type__id'])->get_cmdb_tags($row['isys_obj__id']);

            if (count($tags)) {
                $res = $propertyDao->retrieve_properties(array_keys($tags));

                if (count($res)) {
                    while ($propertyRow = $res->get_row()) {
                        $return[] = [
                            'id'    => null,
                            'const' => isys_check_mk_helper_tag::prepare_valid_tag_name($tags[$propertyRow['id']]),
                            'val'   => $tags[$propertyRow['id']],
                            'sel'   => true,
                            'group' => $propertyRow['const'] . '__' . $propertyRow['key']
                        ];
                    }
                }
            }
        }

        return $return;
    }

    /**
     * Dynamic property callback for dynamic tags.
     *
     * @param   integer $categoryEntryId
     * @param   array   $row
     *
     * @return  array
     */
    public function dynamic_property_callback_dynamic_tags($categoryEntryId, $row)
    {
        $return = [];

        if (class_exists('isys_check_mk_helper_tag')) {
            $groups = isys_check_mk_helper_tag::get_dynamic_tags($row['isys_obj__id'], true);

            if (is_array($groups) && count($groups)) {
                foreach ($groups as $group => $tags) {
                    $tagGroup = null;

                    if (is_numeric($group) && $group > 0) {
                        $groupData = isys_factory_cmdb_dialog_dao::get_instance('isys_check_mk_tag_groups', $this->m_db)->get_data($group);

                        $tagGroup = isys_check_mk_helper_tag::prepare_valid_tag_name($groupData['title']);
                    }

                    foreach ($tags as $tag) {
                        $return[] = [
                            'id'    => null,
                            'const' => isys_check_mk_helper_tag::prepare_valid_tag_name($tag),
                            'val'   => $tag,
                            'sel'   => true,
                            'group' => $tagGroup
                        ];
                    }
                }

            }
        }

        return $return;
    }

    /**
     * Save method for setting specific values by hand.
     *
     * @param   integer $p_category_data_id
     * @param   array   $p_data
     *
     * @return  boolean
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function save_data($p_category_data_id, $p_data)
    {
        if (isset($p_data['tags'])) {
            if (!isys_format_json::is_json_array($p_data['tags'])) {
                if (strpos($p_data['tags'], ',') !== false) {
                    $p_data['tags'] = explode(',', $p_data['tags']);
                }

                $p_data['tags'] = (array) $p_data['tags'];

                $p_data['tags'] = isys_format_json::encode(array_filter(array_map('intval', $p_data['tags'])));
            }
        } else {
            $p_data['tags'] = null;
        }

        return parent::save_data($p_category_data_id, $p_data);
    }

    /**
     * Retrieves the available tags, ready for a "dialog_list".
     *
     * @param   integer $p_obj_id
     * @param   array   $p_selection
     *
     * @return  array
     * @author  Leonard Fischer <lfischer@i-doit.com>
     */
    public function get_tags_for_dialog_list($p_obj_id = null, array $p_selection = null)
    {
        $l_tags = $l_return = [];

        if ($p_obj_id !== null) {
            $l_res = $this->get_data(null, $p_obj_id);

            if (count($l_res) > 0) {
                $l_catdata = $l_res->get_row();

                $l_tags = [];

                if (isys_format_json::is_json_array($l_catdata['isys_catg_cmk_tag_list__tags'])) {
                    $l_tags = isys_format_json::decode($l_catdata['isys_catg_cmk_tag_list__tags']) ?: [];
                }
            }
        }

        if ($p_selection !== null) {
            $l_tags = $p_selection;
        }

        $l_dialog = isys_check_mk_dao::instance($this->m_db)
            ->get_configured_tags();

        // Adding specific "p_arData" values...
        if (is_array($l_dialog) && count($l_dialog) > 0) {
            foreach ($l_dialog as $l_item) {
                $l_return[] = [
                    'id'  => $l_item['isys_check_mk_tags__id'],
                    'val' => '[' . isys_application::instance()->container->get('language')
                            ->get($l_item['isys_check_mk_tag_groups__title']) . '] ' . $l_item['isys_check_mk_tags__display_name'],
                    'sel' => in_array($l_item['isys_check_mk_tags__id'], $l_tags)
                ];
            }
        }

        return $l_return;
    }

    /**
     * @param  array   $p_category_data
     * @param  integer $p_object_id
     * @param  integer $p_status
     *
     * @return mixed
     * @throws isys_exception_validation
     */
    public function sync($p_category_data, $p_object_id, $p_status)
    {
        if (isset($p_category_data['properties']['tags'][C__DATA__VALUE]) && is_array($p_category_data['properties']['tags'][C__DATA__VALUE])) {
            $tagEntries = (new isys_cmdb_dao_dialog($this->m_db, 'isys_check_mk_tags'))->get_data();

            $tags = [];

            foreach ($p_category_data['properties']['tags'][C__DATA__VALUE] as $tag) {
                if (is_array($tag) && isset($tag['id']) && is_numeric($tag['id'])) {
                    $tags[] = $tag['id'];
                } else if (is_numeric($tag)) {
                    $tags[] = $tag;
                } else if (is_string($tag)) {
                    foreach ($tagEntries as $tagEntry) {
                        if ($tag === $tagEntry['isys_check_mk_tags__unique_name'] || $tag === $tagEntry['isys_check_mk_tags__display_name']) {
                            $tags[] = $tagEntry['isys_check_mk_tags__id'];
                        }
                    }
                }
            }

            if (count($tags)) {
                $p_category_data['properties']['tags'][C__DATA__VALUE] = isys_format_json::encode($tags);
            }
        }

        return parent::sync($p_category_data, $p_object_id, $p_status);
    }
}
