<?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\ActivityLogBundle;

use LifeStyle\ActivityLogBundle\Database\UserActionLogManager as DatabaseManager;
use LifeStyle\SamlAuthBundle\Entity\User;
use LifeStyle\SamlAuthBundle\Exceptions\SamlAuthExceptionInterface;
use LifeStyle\SamlAuthBundle\UserHandlerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class ActivityLogHandler
 *
 * @copyright  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package    LifeStyle\ActivityLogBundle
 */
class ActivityLogHandler implements ActivityLogHandlerInterface
{
    /**
     * @var UserHandlerInterface
     */
    private $userHandler;

    /**
     * @var DatabaseManager
     */
    private $databaseManager;

    /**
     * @var Request|null
     */
    private $request;

    /**
     * ActivityLogHandler constructor.
     * @param UserHandlerInterface $userHandler
     * @param DatabaseManager $databaseManager
     * @param Request|null $request
     */
    public function __construct(UserHandlerInterface $userHandler, DatabaseManager $databaseManager, Request $request = null)
    {
        $this->userHandler = $userHandler;
        $this->databaseManager = $databaseManager;
        $this->request = $request;
    }

    /**
     * @param string $controller
     * @param string $action
     * @param string $type
     * @param string|null $request
     * @param string|null $response
     * @param array|null $stats
     */
    public function log($controller, $action, $type, $request = null, $response = null, $stats = null)
    {
        $user = $this->findLoggedInUser();
        if (null === $user) {
            return;
        }

        $this->databaseManager->createUserActionLog(
            $controller,
            $action,
            $type,
            $this->getClientIp(),
            $user,
            $request,
            $response,
            $stats
        );
    }

    /**
     * @return string
     */
    private function getClientIp()
    {
        if (null === $this->request) {
            return '';
        }

        // Search for ip behind elastic load balancer (ELB)
        if ($this->request->headers->has('x-forwarded-for')) {
            $parts = array_map('trim', explode(',', $this->request->headers->get('x-forwarded-for')));
            $ipAddress = filter_var($parts[0], FILTER_VALIDATE_IP);
        }

        // Not behind a ELB
        if (empty($ipAddress)) {
            return $this->request->getClientIp();
        }

        return $ipAddress;
    }

    /**
     * @return User|null
     */
    private function findLoggedInUser()
    {
        try {
            $user = $this->userHandler->getUser();
        } catch (SamlAuthExceptionInterface $exception) {
            return null;
        }
        return $user;
    }
}
