<?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
 *
 */

namespace CentreonClapi;

use Centreon_Object;
use Centreon_Object_Dependency;
use Centreon_Object_Host;
use Centreon_Object_Host_Group;
use Centreon_Object_Meta_Service;
use Centreon_Object_Relation;
use Centreon_Object_Relation_Dependency_Parent_Host;
use Centreon_Object_Relation_Dependency_Parent_Hostgroup;
use Centreon_Object_Relation_Dependency_Parent_Metaservice;
use Centreon_Object_Relation_Dependency_Parent_Servicegroup;
use Centreon_Object_Service_Group;
use Exception;
use PDO;
use PDOException;
use Pimple\Container;

require_once 'centreonObject.class.php';
require_once 'centreonHost.class.php';
require_once 'centreonService.class.php';
require_once 'Centreon/Object/Dependency/Dependency.php';
require_once 'Centreon/Object/Host/Host.php';
require_once 'Centreon/Object/Host/Group.php';
require_once 'Centreon/Object/Service/Group.php';
require_once 'Centreon/Object/Meta/Service.php';
require_once 'Centreon/Object/Relation/Dependency/Parent/Host.php';
require_once 'Centreon/Object/Relation/Dependency/Parent/Hostgroup.php';
require_once 'Centreon/Object/Relation/Dependency/Parent/Servicegroup.php';
require_once 'Centreon/Object/Relation/Dependency/Parent/Metaservice.php';

/**
 * Class
 *
 * @class CentreonDependency
 * @package CentreonClapi
 * @description Class for managing dependency objects
 */
class CentreonDependency extends CentreonObject
{
    public const ORDER_UNIQUENAME = 0;
    public const ORDER_ALIAS = 1;
    public const ORDER_DEP_TYPE = 2;
    public const ORDER_PARENTS = 3;
    public const DEP_TYPE_HOST = 'HOST';
    public const DEP_TYPE_HOSTGROUP = 'HG';
    public const DEP_TYPE_SERVICE = 'SERVICE';
    public const DEP_TYPE_SERVICEGROUP = 'SG';
    public const DEP_TYPE_META = 'META';

    /** @var CentreonService */
    protected $serviceObj;

    /**
     * CentreonDependency constructor
     *
     * @param Container $dependencyInjector
     *
     * @throws PDOException
     */
    public function __construct(Container $dependencyInjector)
    {
        parent::__construct($dependencyInjector);
        $this->serviceObj = new CentreonService($dependencyInjector);
        $this->object = new Centreon_Object_Dependency($dependencyInjector);
        $this->action = 'DEP';
        $this->insertParams = ['dep_name', 'dep_description', 'type', 'parents'];
        $this->nbOfCompulsoryParams = count($this->insertParams);
    }

    /**
     * @param null $parameters
     * @param array $filters
     *
     * @throws Exception
     */
    public function show($parameters = null, $filters = []): void
    {
        $filters = [];
        if (isset($parameters)) {
            $filters = [$this->object->getUniqueLabelField() => '%' . $parameters . '%'];
        }
        $params = ['dep_id', 'dep_name', 'dep_description', 'inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria'];
        $paramString = str_replace('dep_', '', implode($this->delim, $params));
        echo $paramString . "\n";
        $elements = $this->object->getList(
            $params,
            -1,
            0,
            null,
            null,
            $filters
        );
        foreach ($elements as $tab) {
            echo implode($this->delim, $tab) . "\n";
        }
    }

    /**
     * Add action
     *
     * @param null $parameters
     *
     * @throws CentreonClapiException
     * @throws PDOException
     * @return void
     */
    public function add($parameters = null): void
    {
        $params = explode($this->delim, $parameters);
        if (count($params) < $this->nbOfCompulsoryParams) {
            throw new CentreonClapiException(self::MISSINGPARAMETER);
        }
        $addParams = [];
        $addParams[$this->object->getUniqueLabelField()] = $params[self::ORDER_UNIQUENAME];
        $addParams['dep_description'] = $params[self::ORDER_ALIAS];
        $addParams['parents'] = $params[self::ORDER_PARENTS];
        $this->params = array_merge($this->params, $addParams);
        $this->checkParameters();

        switch (strtoupper($params[self::ORDER_DEP_TYPE])) {
            case self::DEP_TYPE_HOST:
                $this->addHostDependency($addParams);
                break;
            case self::DEP_TYPE_HOSTGROUP:
                $this->addHostGroupDependency($addParams);
                break;
            case self::DEP_TYPE_SERVICE:
                $this->addServiceDependency($addParams);
                break;
            case self::DEP_TYPE_SERVICEGROUP:
                $this->addServiceGroupDependency($addParams);
                break;
            case self::DEP_TYPE_META:
                $this->addMetaDependency($addParams);
                break;
            default:
                throw new CentreonClapiException(
                    sprintf(
                        'Unknown type %s. Please choose one of the following host|hg|service|sg|meta',
                        $params[self::ORDER_DEP_TYPE]
                    )
                );
                break;
        }
    }

    /**
     * @param null $parameters
     * @throws CentreonClapiException
     * @return array
     */
    public function initUpdateParameters($parameters = null)
    {
        $params = explode($this->delim, $parameters);
        if (count($params) < self::NB_UPDATE_PARAMS) {
            throw new CentreonClapiException(self::MISSINGPARAMETER);
        }

        $objectId = $this->getObjectId($params[self::ORDER_UNIQUENAME]);
        if ($objectId != 0) {
            if (in_array($params[1], ['comment', 'name', 'description']) && ! preg_match('/^dep_/', $params[1])) {
                $params[1] = 'dep_' . $params[1];
            }
            $params[2] = str_replace('<br/>', "\n", $params[2]);
            $updateParams = [$params[1] => htmlentities($params[2], ENT_QUOTES, 'UTF-8')];
            $updateParams['objectId'] = $objectId;

            return $updateParams;
        }

        throw new CentreonClapiException(self::OBJECT_NOT_FOUND . ':' . $params[self::ORDER_UNIQUENAME]);
    }

    /**
     * List dependencies
     *
     * @param string $parameters | dependency name
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    public function listdep($parameters): void
    {
        $type = $this->getDependencyType($parameters);

        if ($type == '') {
            throw new CentreonClapiException('Could not define type of dependency');
        }

        $depId = $this->getObjectId($parameters);

        // header
        echo implode($this->delim, ['parents', 'children']) . "\n";

        switch ($type) {
            case self::DEP_TYPE_HOST:
                $this->listhostdep($depId);
                break;
            case self::DEP_TYPE_HOSTGROUP:
                $this->listhostgroupdep($depId);
                break;
            case self::DEP_TYPE_SERVICE:
                $this->listservicedep($depId);
                break;
            case self::DEP_TYPE_SERVICEGROUP:
                $this->listservicegroupdep($depId);
                break;
            case self::DEP_TYPE_META:
                $this->listmetadep($depId);
                break;
            default:
                break;
        }
    }

    /**
     * @param $parameters
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    public function delparent($parameters): void
    {
        $this->deleteRelations($parameters, 'parent');
    }

    /**
     * Delete child
     *
     * @param string $parameters | dep_name;children_to_delete
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    public function delchild($parameters): void
    {
        $this->deleteRelations($parameters, 'child');
    }

    /**
     * Add parent
     *
     * @param $parameters
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    public function addparent($parameters): void
    {
        $this->addRelations($parameters, 'parent');
    }

    /**
     * Add child
     *
     * @param $parameters
     *
     * @throws CentreonClapiException
     * @throws PDOException
     * @return void
     */
    public function addchild($parameters): void
    {
        $this->addRelations($parameters, 'child');
    }

    /**
     * Export
     *
     * @param $filterName
     *
     * @return void
     */
    public function export($filterName = null): void
    {
        $this->exportHostDep();
        $this->exportServiceDep();
        $this->exportHostgroupDep();
        $this->exportServicegroupDep();
        $this->exportMetaDep();
    }

    /**
     * Return the type of dependency
     *
     * @param string $dependencyName
     *
     * @throws PDOException
     * @return string
     */
    protected function getDependencyType($dependencyName)
    {
        $sql = "SELECT '" . self::DEP_TYPE_HOST . "' as type
            FROM dependency d, dependency_hostParent_relation rel
            WHERE rel.dependency_dep_id = d.dep_id
            AND d.dep_name = :name
            UNION
            SELECT '" . self::DEP_TYPE_SERVICE . "'
            FROM dependency d, dependency_serviceParent_relation rel
            WHERE rel.dependency_dep_id = d.dep_id
            AND d.dep_name = :name
            UNION
            SELECT '" . self::DEP_TYPE_HOSTGROUP . "'
            FROM dependency d, dependency_hostgroupParent_relation rel
            WHERE rel.dependency_dep_id = d.dep_id
            AND d.dep_name = :name
            UNION
            SELECT '" . self::DEP_TYPE_SERVICEGROUP . "'
            FROM dependency d, dependency_servicegroupParent_relation rel
            WHERE rel.dependency_dep_id = d.dep_id
            AND d.dep_name = :name
            UNION
            SELECT '" . self::DEP_TYPE_META . "'
            FROM dependency d, dependency_metaserviceParent_relation rel
            WHERE rel.dependency_dep_id = d.dep_id
            AND d.dep_name = :name";
        $res = $this->db->query($sql, [':name' => $dependencyName]);
        $row = $res->fetch();

        return $row['type'] ?? '';
    }

    /**
     * @param int $dependencyId
     *
     * @throws PDOException
     * @return string
     */
    protected function getDependencyName(int $dependencyId): string
    {
        $sql = 'SELECT `dep_name` FROM `dependency` WHERE `dep_id` = :depId';
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam(':depId', $dependencyId, PDO::PARAM_INT);
        $stmt->execute();
        $row = $stmt->fetch();

        return $row['dep_name'] ?? '';
    }

    /**
     * Insert new dependency
     *
     * @param string $name
     * @param string $description
     * @param Centreon_Object $parentObj
     * @param string $parentString
     * @param Centreon_Object_Relation $relationObj
     *
     * @throws CentreonClapiException
     * @return void
     */
    protected function insertDependency($name, $description, $parentObj, $parentString, $relationObj)
    {
        $parents = explode('|', $parentString);
        $parentIds = [];
        foreach ($parents as $parent) {
            $idTab = $parentObj->getIdByParameter(
                $parentObj->getUniqueLabelField(),
                [$parent]
            );
            // make sure that all parents exist
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find %s', $parent));
            }
            $parentIds[] = $idTab[0];
        }

        // insert dependency
        $depId = $this->object->insert(
            ['dep_name' => $name, 'dep_description' => $description]
        );
        if (is_null($depId)) {
            throw new CentreonClapiException(sprintf('Could not insert dependency %s', $name));
        }

        // insert relations
        foreach ($parentIds as $parentId) {
            $relationObj->insert($depId, $parentId);
        }
    }

    /**
     * Add host type dependency
     *
     * @param array $params
     *
     * @throws CentreonClapiException
     */
    protected function addHostDependency($params)
    {
        $obj = new Centreon_Object_Host($this->dependencyInjector);
        $relObj = new Centreon_Object_Relation_Dependency_Parent_Host($this->dependencyInjector);
        $this->insertDependency(
            $params['dep_name'],
            $params['dep_description'],
            $obj,
            $params['parents'],
            $relObj
        );
    }

    /**
     * Add hostgroup type dependency
     *
     * @param array $params
     *
     * @throws CentreonClapiException
     */
    protected function addHostGroupDependency($params)
    {
        $obj = new Centreon_Object_Host_Group($this->dependencyInjector);
        $relObj = new Centreon_Object_Relation_Dependency_Parent_Hostgroup($this->dependencyInjector);
        $this->insertDependency(
            $params['dep_name'],
            $params['dep_description'],
            $obj,
            $params['parents'],
            $relObj
        );
    }

    /**
     * @param $params
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addServiceDependency($params)
    {
        $parents = explode('|', $params['parents']);
        $parentIds = [];
        foreach ($parents as $parent) {
            $tmp = explode(',', $parent);
            if (count($tmp) != 2) {
                throw new CentreonClapiException('Incorrect service definition');
            }
            // make sure that all parents exist
            $host = $tmp[0];
            $service = $tmp[1];
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $parentIds[] = $idTab;
        }

        // insert dependency
        $depId = $this->object->insert(
            ['dep_name' => $params['dep_name'], 'dep_description' => $params['dep_description']]
        );
        if (is_null($depId)) {
            throw new CentreonClapiException(sprintf('Could not insert dependency %s', $name));
        }

        // insert relations
        $sql = 'INSERT INTO dependency_serviceParent_relation
            (dependency_dep_id, host_host_id, service_service_id) VALUES (?, ?, ?)';
        foreach ($parentIds as $parentId) {
            $this->db->query($sql, [$depId, $parentId[0], $parentId[1]]);
        }
    }

    /**
     * Add servicegroup type dependency
     *
     * @param array $params
     *
     * @throws CentreonClapiException
     */
    protected function addServiceGroupDependency($params)
    {
        $obj = new Centreon_Object_Service_Group($this->dependencyInjector);
        $relObj = new Centreon_Object_Relation_Dependency_Parent_Servicegroup($this->dependencyInjector);
        $this->insertDependency(
            $params['dep_name'],
            $params['dep_description'],
            $obj,
            $params['parents'],
            $relObj
        );
    }

    /**
     * Add meta type dependency
     *
     * @param array $params
     *
     * @throws CentreonClapiException
     */
    protected function addMetaDependency($params)
    {
        $obj = new Centreon_Object_Meta_Service($this->dependencyInjector);
        $relObj = new Centreon_Object_Relation_Dependency_Parent_Metaservice($this->dependencyInjector);
        $this->insertDependency(
            $params['dep_name'],
            $params['dep_description'],
            $obj,
            $params['parents'],
            $relObj
        );
    }

    /**
     * List host group dependency
     *
     * @param int $depId
     *
     * @throws PDOException
     */
    protected function listhostgroupdep($depId)
    {
        // Parents
        $sql = 'SELECT hg_name
            FROM hostgroup hg, dependency_hostgroupParent_relation rel
            WHERE hg.hg_id = rel.hostgroup_hg_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $parents = [];
        foreach ($rows as $row) {
            $parents[] = $row['hg_name'];
        }

        // Children
        $sql = 'SELECT hg_name
            FROM hostgroup hg, dependency_hostgroupChild_relation rel
            WHERE hg.hg_id = rel.hostgroup_hg_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $children = [];
        foreach ($rows as $row) {
            $children[] = $row['hg_name'];
        }

        $str = implode('|', $parents) . $this->delim;
        $str .= implode('|', $children);
        echo str_replace('||', '|', $str) . "\n";
    }

    /**
     * List service dependency
     *
     * @param int $depId
     *
     * @throws PDOException
     */
    protected function listservicedep($depId)
    {
        // Parents
        $sql = 'SELECT host_name, service_description
            FROM host h, service s, dependency_serviceParent_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.service_service_id = s.service_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $parents = [];
        foreach ($rows as $row) {
            $parents[] = $row['host_name'] . ',' . $row['service_description'];
        }

        // Host children
        $sql = 'SELECT host_name
            FROM host h, dependency_hostChild_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $hostChildren = [];
        foreach ($rows as $row) {
            $hostChildren[] = $row['host_name'];
        }

        // Service children
        $sql = 'SELECT host_name, service_description
            FROM host h, service s, dependency_serviceChild_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.service_service_id = s.service_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $serviceChildren = [];
        foreach ($rows as $row) {
            $serviceChildren[] = $row['host_name'] . ',' . $row['service_description'];
        }

        $strParents = implode('|', $parents) . $this->delim;
        $strChildren = implode('|', $hostChildren) . '|';
        $strChildren .= implode('|', $serviceChildren);
        echo str_replace('||', '|', $strParents . trim($strChildren, '|')) . "\n";
    }

    /**
     * List service group dependency
     *
     * @param int $depId
     *
     * @throws PDOException
     */
    protected function listservicegroupdep($depId)
    {
        // Parents
        $sql = 'SELECT sg_name
            FROM servicegroup sg, dependency_servicegroupParent_relation rel
            WHERE sg.sg_id = rel.servicegroup_sg_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $parents = [];
        foreach ($rows as $row) {
            $parents[] = $row['sg_name'];
        }

        // Children
        $sql = 'SELECT sg_name
            FROM servicegroup sg, dependency_servicegroupChild_relation rel
            WHERE sg.sg_id = rel.servicegroup_sg_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $children = [];
        foreach ($rows as $row) {
            $children[] = $row['sg_name'];
        }

        $str = implode('|', $parents) . $this->delim;
        $str .= implode('|', $children);
        echo str_replace('||', '|', trim($str, '|')) . "\n";
    }

    /**
     * List meta service dependency
     *
     * @param int $depId
     *
     * @throws PDOException
     */
    protected function listmetadep($depId)
    {
        // Parents
        $sql = 'SELECT meta_name
            FROM meta_service m, dependency_metaserviceParent_relation rel
            WHERE m.meta_id = rel.meta_service_meta_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $parents = [];
        foreach ($rows as $row) {
            $parents[] = $row['meta_name'];
        }

        // Children
        $sql = 'SELECT meta_name
            FROM meta_service m, dependency_metaserviceChild_relation rel
            WHERE m.meta_id = rel.meta_service_meta_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $children = [];
        foreach ($rows as $row) {
            $children[] = $row['meta_name'];
        }

        $str = implode('|', $parents) . $this->delim;
        $str .= implode('|', $children);
        echo str_replace('||', '|', trim($str, '|')) . "\n";
    }

    /**
     * List host dependency
     *
     * @param int $depId
     *
     * @throws PDOException
     */
    protected function listhostdep($depId)
    {
        // Parents
        $sql = 'SELECT host_name
            FROM host h, dependency_hostParent_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $parents = [];
        foreach ($rows as $row) {
            $parents[] = $row['host_name'];
        }

        // Host children
        $sql = 'SELECT host_name
            FROM host h, dependency_hostChild_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $hostChildren = [];
        foreach ($rows as $row) {
            $hostChildren[] = $row['host_name'];
        }

        // Service children
        $sql = 'SELECT host_name, service_description
            FROM host h, service s, dependency_serviceChild_relation rel
            WHERE h.host_id = rel.host_host_id
            AND rel.service_service_id = s.service_id
            AND rel.dependency_dep_id = ?';
        $res = $this->db->query($sql, [$depId]);
        $rows = $res->fetchAll();
        $serviceChildren = [];
        foreach ($rows as $row) {
            $serviceChildren[] = $row['host_name'] . ',' . $row['service_description'];
        }

        $strParents = implode('|', $parents) . $this->delim;
        $strChildren = implode('|', $hostChildren) . '|';
        $strChildren .= implode('|', $serviceChildren);
        echo str_replace('||', '|', $strParents . trim($strChildren, '|')) . "\n";
    }

    /**
     * Add relations
     *
     * @param $parameters
     * @param string $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addRelations($parameters, $relType = 'parent')
    {
        $param = explode($this->delim, $parameters);
        if (count($param) < 2) {
            throw new CentreonClapiException(self::MISSINGPARAMETER);
        }

        // get dependency id
        $depId = $this->getObjectId($param[0]);
        if (! $depId) {
            throw new CentreonClapiException(self::OBJECT_NOT_FOUND);
        }

        // get dependency type
        $depType = $this->getDependencyType($param[0]);
        $objectToDelete = $param[1];

        switch ($depType) {
            case self::DEP_TYPE_HOSTGROUP:
                $this->addHostgroupRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_SERVICEGROUP:
                $this->addServicegroupRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_META:
                $this->addMetaRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_HOST:
                $this->addHostRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_SERVICE:
                $this->addServiceRelations($depId, $objectToDelete, $relType);
                break;
            default:
                break;
        }
    }

    /**
     * @param $depId
     * @param $objectToInsert
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addHostgroupRelations($depId, $objectToInsert, $relType)
    {
        $table = 'dependency_hostgroup' . ucfirst($relType) . '_relation';
        $obj = new Centreon_Object_Host_Group($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToInsert]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find host group %s', $objectToInsert));
        }
        $dataField = ['dependency_dep_id' => $depId, 'hostgroup_hg_id' => $ids[0]];
        if ($this->isExistingDependency($table, $dataField)) {
            throw new CentreonClapiException(
                sprintf(
                    'Hostgroup %s is already linked to the dependency %s',
                    $objectToInsert,
                    $this->getDependencyName($depId)
                )
            );
        }
        $sql = "INSERT INTO {$table} (dependency_dep_id, hostgroup_hg_id) VALUES (:depId, :hgId)";
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
        $stmt->bindParam(':hgId', $ids[0], PDO::PARAM_INT);
        $stmt->execute();
    }

    /**
     * @param $depId
     * @param $objectToInsert
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addServicegroupRelations($depId, $objectToInsert, $relType)
    {
        $table = 'dependency_servicegroup' . ucfirst($relType) . '_relation';
        $obj = new Centreon_Object_Service_Group($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToInsert]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find service group %s', $objectToInsert));
        }
        $dataField = ['dependency_dep_id' => $depId, 'servicegroup_sg_id' => $ids[0]];
        if ($this->isExistingDependency($table, $dataField)) {
            throw new CentreonClapiException(
                sprintf(
                    'Servicegroup %s is already linked to the dependency %s',
                    $objectToInsert,
                    $this->getDependencyName($depId)
                )
            );
        }
        $sql = "INSERT INTO {$table} (dependency_dep_id, servicegroup_sg_id) VALUES (:depId, :sgId)";
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
        $stmt->bindParam(':sgId', $ids[0], PDO::PARAM_INT);
        $stmt->execute();
    }

    /**
     * @param $depId
     * @param $objectToInsert
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addMetaRelations($depId, $objectToInsert, $relType)
    {
        $table = 'dependency_metaservice' . ucfirst($relType) . '_relation';
        $obj = new Centreon_Object_Meta_Service($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToInsert]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find meta service %s', $objectToInsert));
        }
        $dataField = ['dependency_dep_id' => $depId, 'meta_service_meta_id' => $ids[0]];
        if ($this->isExistingDependency($table, $dataField)) {
            throw new CentreonClapiException(
                sprintf(
                    'Meta %s already is already linked to the dependency %s',
                    $objectToInsert,
                    $this->getDependencyName($depId)
                )
            );
        }
        $sql = "INSERT INTO {$table} (dependency_dep_id, meta_service_meta_id) VALUES (:depId, :metaId)";
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
        $stmt->bindParam(':metaId', $ids[0], PDO::PARAM_INT);
        $stmt->execute();
    }

    /**
     * @param $depId
     * @param $objectToInsert
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addHostRelations($depId, $objectToInsert, $relType)
    {
        if ($relType == 'parent') {
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToInsert]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToInsert));
            }
            $dataField = ['dependency_dep_id' => $depId, 'host_host_id' => $hostIds[0]];
            if ($this->isExistingDependency('dependency_hostParent_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Host %s is already linked to the dependency %s',
                        $objectToInsert,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_hostParent_relation (dependency_dep_id, host_host_id)
                    VALUES (:depId, :hostId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $hostIds[0], PDO::PARAM_INT);
            $stmt->execute();
        } elseif ($relType == 'child' && strstr($objectToInsert, ',')) { // service child
            [$host, $service] = explode(',', $objectToInsert);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $dataField = [
                'dependency_dep_id' => $depId,
                'host_host_id' => $idTab[0],
                'service_service_id' => $idTab[1],
            ];
            if ($this->isExistingDependency('dependency_serviceChild_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Dependency between service %s and host %s already exists on %s',
                        $service,
                        $host,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_serviceChild_relation (dependency_dep_id, host_host_id, service_service_id)
                    VALUES (:depId, :hostId, :svcId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $idTab[0], PDO::PARAM_INT);
            $stmt->bindParam(':svcId', $idTab[1], PDO::PARAM_INT);
            $stmt->execute();
        } elseif ($relType == 'child') { // host child
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToInsert]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToInsert));
            }
            $dataField = ['dependency_dep_id' => $depId, 'host_host_id' => $hostIds[0]];
            if ($this->isExistingDependency('dependency_hostChild_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Host %s is already linked to the dependency %s',
                        $objectToInsert,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_hostChild_relation (dependency_dep_id, host_host_id)
                    VALUES (:depId, :hostId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $hostIds[0], PDO::PARAM_INT);
            $stmt->execute();
        }
    }

    /**
     * @param $depId
     * @param $objectToInsert
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function addServiceRelations($depId, $objectToInsert, $relType)
    {
        if ($relType == 'parent') {
            if (! strstr($objectToInsert, ',')) {
                throw new CentreonClapiException('Invalid service definition');
            }
            [$host, $service] = explode(',', $objectToInsert);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $dataField = [
                'dependency_dep_id' => $depId,
                'host_host_id' => $idTab[0],
                'service_service_id' => $idTab[1],
            ];
            if ($this->isExistingDependency('dependency_serviceParent_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Dependency between service %s and host %s already exists on %s',
                        $service,
                        $host,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_serviceParent_relation (dependency_dep_id, host_host_id, service_service_id)
                VALUES (:depId, :hostId, :svcId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $idTab[0], PDO::PARAM_INT);
            $stmt->bindParam(':svcId', $idTab[1], PDO::PARAM_INT);
            $stmt->execute();
        } elseif ($relType == 'child' && strstr($objectToInsert, ',')) { // service child
            [$host, $service] = explode(',', $objectToInsert);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(
                    sprintf('Could not find service %s on host %s', $depId, $service, $host)
                );
            }
            $dataField = [
                'dependency_dep_id' => $depId,
                'host_host_id' => $idTab[0],
                'service_service_id' => $idTab[1],
            ];
            if ($this->isExistingDependency('dependency_serviceChild_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Dependency between service %s and host %s already exists on %s',
                        $service,
                        $host,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_serviceChild_relation (dependency_dep_id, host_host_id, service_service_id)
                VALUES (:depId, :hostId, :svcId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $idTab[0], PDO::PARAM_INT);
            $stmt->bindParam(':svcId', $idTab[1], PDO::PARAM_INT);
            $stmt->execute();
        } elseif ($relType == 'child') { // host child
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToInsert]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToInsert));
            }
            $dataField = ['dependency_dep_id' => $depId, 'host_host_id' => $hostIds[0]];
            if ($this->isExistingDependency('dependency_serviceChild_relation', $dataField)) {
                throw new CentreonClapiException(
                    sprintf(
                        'Service %s is already linked to the dependency %s',
                        $objectToInsert,
                        $this->getDependencyName($depId)
                    )
                );
            }
            $sql = 'INSERT INTO dependency_hostChild_relation (dependency_dep_id, host_host_id)
                    VALUES (:depId, :hostId)';
            $stmt = $this->db->prepare($sql);
            $stmt->bindParam(':depId', $depId, PDO::PARAM_INT);
            $stmt->bindParam(':hostId', $hostIds[0], PDO::PARAM_INT);
            $stmt->execute();
        }
    }

    /**
     * @param $parameters
     * @param string $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function deleteRelations($parameters, $relType = 'parent')
    {
        $param = explode($this->delim, $parameters);
        if (count($param) < 2) {
            throw new CentreonClapiException(self::MISSINGPARAMETER);
        }

        // get dependency id
        $depId = $this->getObjectId($param[0]);
        if (! $depId) {
            throw new CentreonClapiException(self::OBJECT_NOT_FOUND);
        }

        // get dependency type
        $depType = $this->getDependencyType($param[0]);
        $objectToDelete = $param[1];

        switch ($depType) {
            case self::DEP_TYPE_HOSTGROUP:
                $this->delHostgroupRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_SERVICEGROUP:
                $this->delServicegroupRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_META:
                $this->delMetaRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_HOST:
                $this->delHostRelations($depId, $objectToDelete, $relType);
                break;
            case self::DEP_TYPE_SERVICE:
                $this->delServiceRelations($depId, $objectToDelete, $relType);
                break;
            default:
                break;
        }
    }

    /**
     * @param string $table
     * @param array $dataField
     *
     * @throws PDOException
     * @return bool
     */
    protected function isExistingDependency(string $table, array $dataField): bool
    {
        $sql = "SELECT `dependency_dep_id`
                FROM {$table} WHERE ";
        foreach ($dataField as $field => $value) {
            $sql .= " {$field} = {$value} AND";
        }
        $sql = rtrim($sql, 'AND');
        $res = $this->db->query($sql);
        $row = $res->fetch();

        return ! empty($row['dependency_dep_id']);
    }

    /**
     * @param $depId
     * @param $objectToDelete
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function delHostgroupRelations($depId, $objectToDelete, $relType)
    {
        $table = 'dependency_hostgroup' . ucfirst($relType) . '_relation';
        $sql = "DELETE FROM {$table}
            WHERE dependency_dep_id = ?
            AND hostgroup_hg_id = ?";
        $obj = new Centreon_Object_Host_Group($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToDelete]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find host group %s', $objectToDelete));
        }
        $this->db->query($sql, [$depId, $ids[0]]);
    }

    /**
     * @param $depId
     * @param $objectToDelete
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function delServicegroupRelations($depId, $objectToDelete, $relType)
    {
        $table = 'dependency_servicegroup' . ucfirst($relType) . '_relation';
        $sql = "DELETE FROM {$table}
            WHERE dependency_dep_id = ?
            AND servicegroup_sg_id = ?";
        $obj = new Centreon_Object_Service_Group($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToDelete]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find service group %s', $objectToDelete));
        }
        $this->db->query($sql, [$depId, $ids[0]]);
    }

    /**
     * @param $depId
     * @param $objectToDelete
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function delMetaRelations($depId, $objectToDelete, $relType)
    {
        $table = 'dependency_metaservice' . ucfirst($relType) . '_relation';

        $sql = "DELETE FROM {$table}
            WHERE dependency_dep_id = ?
            AND meta_service_meta_id = ?";
        $obj = new Centreon_Object_Meta_Service($this->dependencyInjector);
        $ids = $obj->getIdByParameter($obj->getUniqueLabelField(), [$objectToDelete]);
        if (! count($ids)) {
            throw new CentreonClapiException(sprintf('Could not find meta service %s', $objectToDelete));
        }
        $this->db->query($sql, [$depId, $ids[0]]);
    }

    /**
     * @param $depId
     * @param $objectToDelete
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function delHostRelations($depId, $objectToDelete, $relType)
    {
        if ($relType == 'parent') {
            $sql = 'DELETE FROM dependency_hostParent_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?';
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToDelete]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToDelete));
            }
            $params = [$depId, $hostIds[0]];
        } elseif ($relType == 'child' && strstr($objectToDelete, ',')) { // service child
            $sql = 'DELETE FROM dependency_serviceChild_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?
                AND service_service_id = ?';
            [$host, $service] = explode(',', $objectToDelete);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $params = [$depId, $idTab[0], $idTab[1]];
        } elseif ($relType == 'child') { // host child
            $sql = 'DELETE FROM dependency_hostChild_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?';
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToDelete]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToDelete));
            }
            $params = [$depId, $hostIds[0]];
        }
        $this->db->query($sql, $params);
    }

    /**
     * @param $depId
     * @param $objectToDelete
     * @param $relType
     *
     * @throws CentreonClapiException
     * @throws PDOException
     */
    protected function delServiceRelations($depId, $objectToDelete, $relType)
    {
        if ($relType == 'parent') {
            $sql = 'DELETE FROM dependency_serviceParent_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?
                AND service_service_id = ?';
            if (! strstr($objectToDelete, ',')) {
                throw new CentreonClapiException('Invalid service definition');
            }
            [$host, $service] = explode(',', $objectToDelete);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $params = [$depId, $idTab[0], $idTab[1]];
        } elseif ($relType == 'child' && strstr($objectToDelete, ',')) { // service child
            $sql = 'DELETE FROM dependency_serviceChild_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?
                AND service_service_id = ?';
            [$host, $service] = explode(',', $objectToDelete);
            $idTab = $this->serviceObj->getHostAndServiceId($host, $service);
            if (! count($idTab)) {
                throw new CentreonClapiException(sprintf('Could not find service %s on host %s', $service, $host));
            }
            $params = [$depId, $idTab[0], $idTab[1]];
        } elseif ($relType == 'child') { // host child
            $sql = 'DELETE FROM dependency_hostChild_relation
                WHERE dependency_dep_id = ?
                AND host_host_id = ?';
            $hostObj = new Centreon_Object_Host($this->dependencyInjector);
            $hostIds = $hostObj->getIdByParameter($hostObj->getUniqueLabelField(), [$objectToDelete]);
            if (! count($hostIds)) {
                throw new CentreonClapiException(sprintf('Could not find host %s', $objectToDelete));
            }
            $params = [$depId, $hostIds[0]];
        }
        $this->db->query($sql, $params);
    }

    /**
     * @throws PDOException
     * @return void
     */
    protected function exportHostDep()
    {
        $sql = 'SELECT dep_id, dep_name, dep_description, inherits_parent,
            execution_failure_criteria, notification_failure_criteria, dep_comment, host_name
            FROM dependency d, dependency_hostParent_relation rel, host h
            WHERE d.dep_id = rel.dependency_dep_id
            AND rel.host_host_id = h.host_id
            ORDER BY dep_name';
        $res = $this->db->query($sql);
        $rows = $res->fetchAll();
        $previous = 0;
        $paramArr = ['inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria', 'dep_comment'];
        foreach ($rows as $row) {
            if ($row['dep_id'] != $previous) { // add dependency
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADD', $row['dep_name'], $row['dep_description'], self::DEP_TYPE_HOST, $row['host_name']]
                    ) . "\n";
                foreach ($row as $k => $v) {
                    if (! in_array($k, $paramArr)) {
                        continue;
                    }
                    // setparam
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'SETPARAM', $row['dep_name'], $k, $v]
                        ) . "\n";
                }
                // add host children
                $childSql = 'SELECT host_name
                    FROM host h, dependency_hostChild_relation rel
                    WHERE h.host_id = rel.host_host_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['host_name']]
                        ) . "\n";
                }

                // add service children
                $childSql = 'SELECT host_name, service_description
                    FROM host h, service s, dependency_serviceChild_relation rel
                    WHERE h.host_id = rel.host_host_id
                    AND rel.service_service_id = s.service_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['host_name'] . ',' . $childRow['service_description']]
                        ) . "\n";
                }
            } else {
                // addparent
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADDPARENT', $row['dep_name'], $row['host_name']]
                    ) . "\n";
            }
            $previous = $row['dep_id'];
        }
    }

    /**
     * @throws PDOException
     * @return void
     */
    protected function exportServiceDep()
    {
        $sql = 'SELECT dep_id, dep_name, dep_description, inherits_parent,
            execution_failure_criteria, notification_failure_criteria, dep_comment, host_name, service_description
            FROM dependency d, dependency_serviceParent_relation rel, host h, service s
            WHERE d.dep_id = rel.dependency_dep_id
            AND h.host_id = rel.host_host_id
            AND rel.service_service_id = s.service_id
            ORDER BY dep_name';
        $res = $this->db->query($sql);
        $rows = $res->fetchAll();
        $previous = 0;
        $paramArr = ['inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria', 'dep_comment'];
        foreach ($rows as $row) {
            if ($row['dep_id'] != $previous) { // add dependency
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADD', $row['dep_name'], $row['dep_description'], self::DEP_TYPE_SERVICE, $row['host_name'] . ',' . $row['service_description']]
                    ) . "\n";
                foreach ($row as $k => $v) {
                    if (! in_array($k, $paramArr)) {
                        continue;
                    }
                    // setparam
                    $v = CentreonUtils::convertLineBreak($v);
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'SETPARAM', $row['dep_name'], $k, html_entity_decode($v, ENT_QUOTES, 'UTF-8')]
                        ) . "\n";
                }
                // add host children
                $childSql = 'SELECT host_name
                    FROM host h, dependency_hostChild_relation rel
                    WHERE h.host_id = rel.host_host_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['host_name']]
                        ) . "\n";
                }

                // add service children
                $childSql = 'SELECT host_name, service_description
                    FROM host h, service s, dependency_serviceChild_relation rel
                    WHERE h.host_id = rel.host_host_id
                    AND rel.service_service_id = s.service_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['host_name'] . ',' . $childRow['service_description']]
                        ) . "\n";
                }
            } else {
                // addparent
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADDPARENT', $row['dep_name'], $row['host_name'] . ',' . $row['service_description']]
                    ) . "\n";
            }
            $previous = $row['dep_id'];
        }
    }

    /**
     * @throws PDOException
     * @return void
     */
    protected function exportHostgroupDep()
    {
        $sql = 'SELECT dep_id, dep_name, dep_description, inherits_parent,
            execution_failure_criteria, notification_failure_criteria, dep_comment, hg_name
            FROM dependency d, dependency_hostgroupParent_relation rel, hostgroup hg
            WHERE d.dep_id = rel.dependency_dep_id
            AND rel.hostgroup_hg_id = hg.hg_id
            ORDER BY dep_name';
        $res = $this->db->query($sql);
        $rows = $res->fetchAll();
        $previous = 0;
        $paramArr = ['inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria', 'dep_comment'];
        foreach ($rows as $row) {
            if ($row['dep_id'] != $previous) { // add dependency
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADD', $row['dep_name'], $row['dep_description'], self::DEP_TYPE_HOSTGROUP, $row['hg_name']]
                    ) . "\n";
                foreach ($row as $k => $v) {
                    if (! in_array($k, $paramArr)) {
                        continue;
                    }
                    // setparam
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'SETPARAM', $row['dep_name'], $k, $v]
                        ) . "\n";
                }
                // add children
                $childSql = 'SELECT hg_name
                    FROM hostgroup hg, dependency_hostgroupChild_relation rel
                    WHERE hg.hg_id = rel.hostgroup_hg_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['hg_name']]
                        ) . "\n";
                }
            } else {
                // addparent
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADDPARENT', $row['dep_name'], $row['hg_name']]
                    ) . "\n";
            }
            $previous = $row['dep_id'];
        }
    }

    /**
     * @throws PDOException
     * @return void
     */
    protected function exportServicegroupDep()
    {
        $sql = 'SELECT dep_id, dep_name, dep_description, inherits_parent,
            execution_failure_criteria, notification_failure_criteria, dep_comment, sg_name
            FROM dependency d, dependency_servicegroupParent_relation rel, servicegroup sg
            WHERE d.dep_id = rel.dependency_dep_id
            AND rel.servicegroup_sg_id = sg.sg_id
            ORDER BY dep_name';
        $res = $this->db->query($sql);
        $rows = $res->fetchAll();
        $previous = 0;
        $paramArr = ['inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria', 'dep_comment'];
        foreach ($rows as $row) {
            if ($row['dep_id'] != $previous) { // add dependency
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADD', $row['dep_name'], $row['dep_description'], self::DEP_TYPE_SERVICEGROUP, $row['sg_name']]
                    ) . "\n";
                foreach ($row as $k => $v) {
                    if (! in_array($k, $paramArr)) {
                        continue;
                    }
                    // setparam
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'SETPARAM', $row['dep_name'], $k, $v]
                        ) . "\n";
                }
                // add children
                $childSql = 'SELECT sg_name
                    FROM servicegroup sg, dependency_servicegroupChild_relation rel
                    WHERE sg.sg_id = rel.servicegroup_sg_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['sg_name']]
                        ) . "\n";
                }
            } else {
                // addparent
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADDPARENT', $row['dep_name'], $row['sg_name']]
                    ) . "\n";
            }
            $previous = $row['dep_id'];
        }
    }

    /**
     * @throws PDOException
     * @return void
     */
    protected function exportMetaDep()
    {
        $sql = 'SELECT dep_id, dep_name, dep_description, inherits_parent,
            execution_failure_criteria, notification_failure_criteria, dep_comment, meta_name
            FROM dependency d, dependency_metaserviceParent_relation rel, meta_service m
            WHERE d.dep_id = rel.dependency_dep_id
            AND rel.meta_service_meta_id = m.meta_id
            ORDER BY dep_name';
        $res = $this->db->query($sql);
        $rows = $res->fetchAll();
        $previous = 0;
        $paramArr = ['inherits_parent', 'execution_failure_criteria', 'notification_failure_criteria', 'dep_comment'];
        foreach ($rows as $row) {
            if ($row['dep_id'] != $previous) { // add dependency
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADD', $row['dep_name'], $row['dep_description'], self::DEP_TYPE_META, $row['meta_name']]
                    ) . "\n";
                foreach ($row as $k => $v) {
                    if (! in_array($k, $paramArr)) {
                        continue;
                    }
                    // setparam
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'SETPARAM', $row['dep_name'], $k, $v]
                        ) . "\n";
                }
                // add children
                $childSql = 'SELECT meta_name
                    FROM meta_service m, dependency_metaserviceChild_relation rel
                    WHERE m.meta_id = rel.meta_service_meta_id
                    AND rel.dependency_dep_id = ?';
                $res = $this->db->query($childSql, [$row['dep_id']]);
                $childRows = $res->fetchAll();
                foreach ($childRows as $childRow) {
                    echo
                        implode(
                            $this->delim,
                            [$this->action, 'ADDCHILD', $row['dep_name'], $childRow['meta_name']]
                        ) . "\n";
                }
            } else {
                // addparent
                echo
                    implode(
                        $this->delim,
                        [$this->action, 'ADDPARENT', $row['dep_name'], $row['meta_name']]
                    ) . "\n";
            }
            $previous = $row['dep_id'];
        }
    }
}
