<?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  2016 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\WebserviceBundle\Services\UserSearch\Advanced\DataProvider\Doctrine;

use Sso\WebserviceBundle\Event\Factory as EventFactory;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\DataProvider\Doctrine\QueryBuilder\Helper\Transformer;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\DataProvider\Doctrine\QueryBuilder\QueryBuilder;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\DataProvider\HandlerInterface;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\RequestData\UserSearch as RequestDTO;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\ResponseData\Users as ResponseDTO;
use Sso\WebserviceBundle\Services\UserSearch\Advanced\Factory;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

/**
 * Class Handler
 * @package Sso\WebserviceBundle\Services\UserSearch\Advanced\DataProvider\Doctrine
 */
final class Handler implements HandlerInterface
{
    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    /**
     * @var EventFactory
     */
    private $eventFactory;

    /**
     * @var EntityManagerInterface
     */
    private $entityManager;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * Handler constructor.
     * @param EventDispatcherInterface $eventDispatcher
     * @param EventFactory $eventFactory
     * @param EntityManagerInterface $entityManager
     * @param LoggerInterface $logger
     */
    public function __construct(
        EventDispatcherInterface $eventDispatcher,
        EventFactory $eventFactory,
        EntityManagerInterface $entityManager,
        LoggerInterface $logger
    ) {
        $this->eventDispatcher = $eventDispatcher;
        $this->eventFactory = $eventFactory;
        $this->entityManager = $entityManager;
        $this->logger = $logger;
    }

    /**
     * @param RequestDTO $requestDTO
     * @param Factory $factory
     * @return ResponseDTO
     */
    public function getResponseDTO(RequestDTO $requestDTO, Factory $factory)
    {
        $queryBuilder = $this->createQueryBuilder();
        $countResults = $queryBuilder->countQueryResults($requestDTO);

        $responseDTO = $factory->responseData()->users();
        $responseDTO->setCount($countResults);
        $responseDTO->setOffset($requestDTO->getOffset());
        $responseDTO->setLimit($requestDTO->getLimit());
        $responseDTO->setOrderBy($requestDTO->getOrderBy());
        $responseDTO->setOrderDir($requestDTO->getOrderDir());
        $responseDTO->setFullResponse($requestDTO->getFullResponse());

        if (0 < $countResults) {
            $userModels = $queryBuilder->getQueryResults($requestDTO);
            foreach ($userModels as $userModel) {
                $user = $factory->responseData()->user()->setFromUserModel(
                    $userModel,
                    $requestDTO->getFullResponse()
                );
                $responseDTO->addUser($user);
            }
        }

        return $responseDTO;
    }

    /**
     * @return QueryBuilder
     */
    private function createQueryBuilder()
    {
        return new QueryBuilder(
            $this->eventDispatcher,
            $this->eventFactory,
            $this->entityManager,
            $this->logger,
            new Transformer()
        );
    }
}
