<?php
/**
 * i-doit - Documentation and CMDB solution for IT environments
 *
 * This file is part of the i-doit framework. Modify at your own risk.
 *
 * Please visit http://www.i-doit.com/license for a full copyright and license information.
 *
 * @version     1.10
 * @package     i-doit
 * @author      synetics GmbH
 * @copyright   synetics GmbH
 * @url         http://www.i-doit.com
 * @license     http://www.i-doit.com/license
 */
namespace idoit\Model\Summary;

use idoit\Component\ContainerFacade;
use idoit\Component\Protocol\ContainerAware;
use idoit\Component\Provider\DiInjectable;
use idoit\Component\Provider\Singleton;
use idoit\Exception\Exception;

/**
 * i-doit Summaries
 *
 * @package     i-doit
 * @subpackage  Core
 * @author      Dennis Stücken <dstuecken@synetics.de>
 * @copyright   synetics GmbH
 * @license     http://www.i-doit.com/license
 */
class SystemSummary implements Summarizable, ContainerAware
{
    use DiInjectable, Singleton;

    /**
     * Dao component for querying the database
     *
     * @var \isys_component_dao
     */
    protected $queryDao;

    /**
     * Summary namespace (cmdb.lists, cmdb.category, ...)
     *
     * @var string
     */
    protected $namespace = 'system';

    /**
     * Increment summary
     *
     * @param     $key
     * @param int $incrementValue
     *
     * @return $this
     * @throws \isys_exception_dao
     */
    public function increment($key, $incrementValue = 1)
    {
        $this->queryDao->update(
            sprintf(
                'UPDATE isys_summary SET isys_summary__count = isys_summary__count + %d WHERE isys_summary__namespace = "%s" AND isys_summary__key = "%s";',
                $incrementValue,
                $this->namespace,
                $key
            )
        );

        return $this;
    }

    /**
     * Decrement summary by 1 on default
     *
     * @param     $key
     * @param int $decrementValue
     *
     * @return $this
     * @throws \isys_exception_dao
     */
    public function decrement($key, $decrementValue = 1)
    {
        $this->queryDao->update(
            sprintf(
                'UPDATE isys_summary SET isys_summary__count = isys_summary__count - %d WHERE isys_summary__namespace = "%s" AND isys_summary__key = "%s" AND isys_summary__count > 0;',
                $decrementValue,
                $this->namespace,
                $key
            )
        );

        return $this;
    }

    /**
     * Concat arguments
     *
     * @param string
     * @param string
     * @param ...
     *
     * @return string
     */
    public function concat( /* ...args */)
    {
        return implode('.', func_get_args());
    }

    /**
     * Get summary
     *
     * @param $key
     *
     * @return int
     * @throws \isys_exception_database
     */
    public function get($key)
    {
        return (int) $this->queryDao->retrieve(
            sprintf(
                'SELECT isys_summary__count AS count FROM isys_summary WHERE isys_summary__namespace = "%s" AND isys_summary__key = "%s";',
                $this->namespace,
                $key
            )
        )
            ->get_row_value('count');
    }

    /**
     * Set summary
     *
     * @param     $key
     * @param int $count
     *
     * @return $this
     * @throws \isys_exception_dao
     */
    public function set($key, $count = 0)
    {
        $this->queryDao->update(
            sprintf(
                'INSERT INTO isys_summary (isys_summary__namespace, isys_summary__key, isys_summary__count) VALUES ("%s", "%s", "%s") ON DUPLICATE KEY UPDATE isys_summary__count = "%s";',
                $this->namespace,
                $key,
                $count,
                $count
            )
        );

        return $this;
    }

    /**
     * @param $key
     *
     * @return $this
     */
    public function remove($key)
    {
        $this->queryDao->update(
            sprintf(
                'DELETE FROM isys_summary WHERE isys_summary__namespace = "%s" AND isys_summary__key = "%s";',
                $this->namespace,
                $key
            )
        );

        return $this;
    }

    /**
     * Summary constructor.
     *
     * @param ContainerFacade|null $containerFacade
     */
    public function __construct(ContainerFacade $containerFacade = null)
    {
        if (!$containerFacade)
        {
            $this->setDi(\isys_application::instance()->container);
        }

        if (!$this->getDi()->has('database'))
        {
            throw new Exception('Error. Database service does not exist (In SystemSummary::construct).');
        }

        $this->queryDao = \isys_component_dao::instance($this->getDi()->database);
    }
} // class