<?php

/*
 * This file is part of Phraseanet
 *
 * (c) 2005-2014 Alchemy
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Alchemy\Phrasea\Model\Repositories;

use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Model\Entities\FeedItem;
use Alchemy\Phrasea\Model\Entities\User;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

/**
 * FeedItemRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class FeedItemRepository extends EntityRepository
{
    /**
     * Checks if a record is published in a public feed.
     *
     * @param int $sbas_id
     * @param int $record_id
     *
     * @return bool
     */
    public function isRecordInPublicFeed($sbas_id, $record_id)
    {
        $dql = 'SELECT COUNT(i)
            FROM Phraseanet:FeedItem i
            JOIN i.entry e
            JOIN e.feed f
            WHERE i.sbasId = :sbas_id
                AND i.recordId = :record_id
                AND f.public = true';

        $query = $this->_em->createQuery($dql);
        $query->setParameters(['sbas_id' => $sbas_id, 'record_id' => $record_id]);

        return $query->getSingleScalarResult() > 0;
    }

    /**
     * Gets latest items from public feeds.
     *
     * @param Application $app
     * @param integer     $nbItems
     *
     * @return FeedItem[] An array of FeedItem
     */
    public function loadLatest(Application $app, $nbItems = 20)
    {
        $execution = 0;
        $items = [];

        do {
            $dql = 'SELECT i
                FROM Phraseanet:FeedItem i
                JOIN i.entry e
                JOIN e.feed f
                WHERE f.public = true ORDER BY i.createdOn DESC';

            $query = $this->_em->createQuery($dql);
            $query
                ->setFirstResult((integer) $nbItems * $execution)
                ->setMaxResults((integer) $nbItems);

            $result = $query->getResult();

            foreach ($result as $item) {
                try {
                    $record = $item->getRecord($app);
                } catch (NotFoundHttpException $e) {
                    $app['orm.em']->remove($item);
                    continue;
                } catch (\Exception_Record_AdapterNotFound $e) {
                    $app['orm.em']->remove($item);
                    continue;
                }

                if (null !== $preview = $record->get_subdef('preview')) {
                    if (null !== $permalink = $preview->get_permalink()) {
                        $items[] = $item;

                        if (count($items) >= $nbItems) {
                            break;
                        }
                    }
                }
            }

            $app['orm.em']->flush();
            $execution++;
        } while (count($items) < $nbItems && count($result) !== 0);

        return $items;
    }

    public function getItemsCount(User $user, $databoxId = null, $recordId = null)
    {
        $qb = $this->createQueryBuilder('fi');
        $qb->select('count(fi)');
        $qb->innerjoin('fi.entry', 'fe');
        $qb->innerjoin('fe.publisher', 'fp');

        $qb->where($qb->expr()->eq('fp.user', ':publisher'));
        $qb->setParameter(':publisher', $user);

        if ($databoxId != null) {
            $qb->andWhere('fi.sbasId = :databoxId');
            $qb->setParameter(':databoxId', $databoxId);
        }

        if ($recordId != null) {
            $qb->andWhere('fi.recordId = :recordId');
            $qb->setParameter(':recordId', $recordId);
        }

        return  $qb->getQuery()->getSingleScalarResult();
    }

    public function getLastItems(User $user, $databoxId = null, $recordId = null, $nbItems = 200)
    {
        $qb = $this->createQueryBuilder('fi');
        $qb->innerjoin('fi.entry', 'fe');
        $qb->innerjoin('fe.publisher', 'fp');

        $qb->where($qb->expr()->eq('fp.user', ':publisher'));
        $qb->setParameter(':publisher', $user);

        if ($databoxId != null) {
            $qb->andWhere('fi.sbasId = :databoxId');
            $qb->setParameter(':databoxId', $databoxId);
        }

        if ($recordId != null) {
            $qb->andWhere('fi.recordId = :recordId');
            $qb->setParameter(':recordId', $recordId);
        }

        $qb->orderBy('fi.id', 'DESC');
        $qb->setMaxResults($nbItems);

        return $qb->getQuery()->getResult();
    }
}
