<?php 

namespace NPS\Repository;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use NPS\Entity\IEntity;
use NPS\Model\AbstractToken;
use NPS\Factory\TokenFactory;
use NPS\Entity\AbstractTokenEntity;
use NPS\Entity\UserActivationTokenEntity;
use NPS\Entity\PasswordResetTokenEntity;

/**
 * Reset token repository class
 * @author Lukas Korinek
 */
final class TokenRepository implements IObjectRepository
{

    const TOKEN_PASSWORD_RESET = 'password_reset';
    const TOKEN_USER_ACTIVATION = 'user_activation';

    /** @var EntityRepository $entityRepository */
    private $activationEntityRepository;

    /** @var EntityRepository $entityRepository */
    private $resetEntityRepository;

    /** @var EntityRepository $entityRepository */
    private $entityRepository;

    /** @var TokenFactory $factory */
    private $factory;

    public function __construct(EntityManagerInterface $em, TokenFactory $factory)
    {
        $this->entityRepository = $em->getRepository(AbstractTokenEntity::class);
        $this->resetEntityRepository = $em->getRepository(PasswordResetTokenEntity::class);
        $this->activationEntityRepository = $em->getRepository(UserActivationTokenEntity::class);
        $this->factory = $factory;
    }

    /**
     * @inheritdoc
     */
    public function getById($id)
    {
        $entity = $this->entityRepository->find($id);
        return $entity ? $this->factory->make($entity) : null;
    }

    /**
     * Gets a reset token by its hash
     * @param string $type Requested token type, refer to the class constrants
     * @param string $hash 
     * @return AbstractToken|null
     */
    public function getByHash($type, $hash)
    {
        switch($type)
        {
            case self::TOKEN_PASSWORD_RESET: $entity = $this->resetEntityRepository->findOneBy(['hash' => $hash]); break;
            case self::TOKEN_USER_ACTIVATION: $entity = $this->activationEntityRepository->findOneBy(['hash' => $hash]); break;
        }
        
        return $entity ? $this->factory->make($entity) : null;
    }

}

