<?php
namespace OfficeBrain\Bundle\UserBundle\Provider;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Userprovider
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class UserProvider implements UserProviderInterface
{
    private $userRepository;

    public function __construct( $serviceContainer, $userRepository, $instanceMasterRepository)
    {
        $this->serviceContainer = $serviceContainer;
        $this->request = $this->serviceContainer->get('request');
        $this->userRepository = $userRepository;
        $this->instanceMasterRepository = $instanceMasterRepository;
    }

    public function loadUserByUsername($username)
    {
        $hostName = (isset($_SERVER['HTTP_X_FORWARDED_HOST']) && $_SERVER['HTTP_X_FORWARDED_HOST']!='')?$_SERVER['HTTP_X_FORWARDED_HOST']:$this->request->getHost();;
        $subDomain = null;
        preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $hostName, $subDomain);
        if($hostName!='localhost' && empty($subDomain)) {
            $hostName = "www.".$hostName;
        }

        $instanceData = $this->instanceMasterRepository->findByDomain($hostName);
        $instanceId = ($instanceData && !empty($instanceData->getId()))?$instanceData->getId():$this->serviceContainer->getParameter('default_main_instance_id'); // Set This instance Id in user provider also
        $instanceType = ($instanceData && !empty($instanceData->getInstanceType()))?$instanceData->getInstanceType():$this->serviceContainer->getParameter('default_main_instance_type'); // Set This instance Id in user provider also

        $query = $this->userRepository
            ->createQueryBuilder('u')
            ->where('u.email = :email')
            ->andWhere('u.status = :status')
            ->setParameter('email', $username)
            ->setParameter('status', 'active')
            ->andWhere("u.instanceId=:instanceId")->setParameter('instanceId', $instanceId)
            ->andWhere("u.instanceType=:instanceType")->setParameter('instanceType', $instanceType)
            ->andWhere("u.deletedAt is NULL")
            ->getQuery();
        try {
            // The Query::getSingleResult() method throws an exception
            // if there is no record matching the criteria.
            $user = $query->getSingleResult();
        } catch (NoResultException $e) {
            $message = sprintf(
                'Unable to find an active Customer object identified by "%s".',
                $username
            );
            throw new UsernameNotFoundException($message, 0, $e);
        }

        return $user;
    }

    public function refreshUser(UserInterface $user)
    {
        $class = get_class($user);

        if (!$this->supportsClass($class)) {
            throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
        }

        return $this->userRepository->find($user->getId());
    }

    public function supportsClass($class)
    {
        return $class === $this->userRepository->getClassName();
    }
}
