<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace LifeStyle\Tools\DbLogBundle\Logger;

use Monolog\Handler\AbstractProcessingHandler;
use LifeStyle\Tools\DbLogBundle\Entity\SystemLog;
use LifeStyle\Tools\DbLogBundle\Entity\SystemLogData;

/**
 * Class DatabaseHandler
 * @package LifeStyle\Tools\DbLogBundle\Logger
 */
class DatabaseHandler extends AbstractProcessingHandler
{
    /**
     * @var bool
     */
    protected $disabled = false;

    /**
     * @var \Symfony\Component\DependencyInjection\Container
     */
    protected $container;

    /**
     * @param \Symfony\Component\DependencyInjection\Container $container
     */
    public function setContainer($container)
    {
        $this->container = $container;
    }

    /**
     * @param bool $enable
     */
    public function enable($enable = true)
    {
        $this->disable(!$enable);
    }

    /**
     * Disable/enable log-handler
     * @param bool $disable
     */
    public function disable($disable = true)
    {
        $this->disabled = (bool)$disable;
    }

    /**
     * Check if log-handler is disabled
     * @return bool
     */
    public function isDisabled()
    {
        return $this->disabled;
    }

    /**
     * {@inheritdoc}
     */
    protected function write(array $record)
    {
        // Check disabled, console and log level
        if ($this->isDisabled() || php_sapi_name() == 'cli' || $record['level'] < $this->level) {
            return;
        }

        $serverData = $record['extra']['serverData'];
        unset($record['extra']['serverData']);
        $extraLog = implode('|||', $record['extra']);

        // Disable temporary to prevent from infinite loops, if doctrine channel is enabled for logging
        $this->disable();

        try {
            $entity = new SystemLog();
            $dataEntity = new SystemLogData();
            $dataEntity
                ->setId($entity->getId())
                ->setLog($record['message'])
                ->setServerData($serverData)
                ->setSystemLog($entity);
            $entity->setLevel($record['level'])
                ->setChannel($record['channel'])
                ->setExtras($extraLog)
                ->setSystemLogData($dataEntity);
            $this->entityManager()->persist($dataEntity);
            $this->entityManager()->persist($entity);
            $this->entityManager()->flush($dataEntity);
            $this->entityManager()->flush($entity);
        } catch (\Exception $e) {

            // Fallback to just writing to php error logs if something really bad happens
            error_log($record['message']);
            error_log($e->getMessage());
        }
        $this->enable();
    }

    /**
     * @return \Doctrine\Common\Persistence\ObjectManager|object
     * @throws \Exception
     */
    protected function entityManager()
    {
        return $this->container->get('doctrine')->getManager();
    }
}
