<?php

namespace CacheBundle\Repository;

use CacheBundle\Entity\SourceList;
use Doctrine\ORM\EntityRepository;

/**
 * SourceListRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class SourceListRepository extends EntityRepository
{

    /**
     * Get QueryBuilder for list of sourceLists for the user
     *
     * @param integer $user       A User entity id.
     * @param array   $order      Array of order config where key - is field name
     *                            and value is order direction.
     * @param boolean $onlyShared Show only shared source lists if set.
     *
     * @return \Doctrine\ORM\QueryBuilder
     */
    public function getSourcesListsQB($user, array $order = [], $onlyShared = false)
    {
        $expr = $this->_em->getExpressionBuilder();

        $qb = $this->createQueryBuilder('SourceList')
            ->addSelect('partial User.{id, firstName, lastName}')
            ->join('SourceList.user', 'User')
            ->where($expr->eq('SourceList.user', ':user'))
            ->setParameter(':user', $user);

        if ($onlyShared) {
            $qb->andWhere($expr->eq('SourceList.isGlobal', 1));
        } else {
            $qb->orWhere($expr->eq('SourceList.isGlobal', 1));
        }

        foreach ($order as $field => $direction) {
            $qb->addOrderBy("SourceList.{$field}", $direction);
        }

        return $qb;
    }

    /**
     * Get concrete SourceLists for the user.
     *
     * @param integer $id   A SourceList entity id.
     * @param integer $user A User entity id.
     *
     * @return SourceList|null
     */
    public function getSourcesLists($id, $user)
    {
        $expr = $this->_em->getExpressionBuilder();

        return $this->getSourcesListsQB($user)
            ->andWhere($expr->eq('SourceList.id', ':id'))
            ->setParameter('id', $id)
            ->getQuery()
            ->getOneOrNullResult();
    }

    /**
     * Remove all source list ids which not exists, not global or not owned by
     * specified user.
     *
     * @param array   $ids  List of requested source list ids.
     *
     * @param integer $user A User entity id.
     *
     * @return integer[]
     */
    public function sanitizeIds(array $ids, $user)
    {
        $expr = $this->_em->getExpressionBuilder();

        return array_map(function (array $result) {
            return $result['id'];
        }, $this->getSourcesListsQB($user)
            ->select('SourceList.id')
            ->andWhere($expr->in('SourceList', ':ids'))
            ->setParameter('ids', $ids)
            ->getQuery()
            ->getArrayResult());
    }

    /**
     * @param integer $user A User entity id.
     *
     * @return integer[]
     */
    public function getAvailableIdsForUser($user)
    {
        return \nspl\a\map(
            \nspl\op\itemGetter('id'),
            $this->getSourcesListsQB($user)
                ->select('SourceList.id')
                ->getQuery()
                ->getArrayResult()
        );
    }
}
