<?php

namespace Doctrine\ORM;

use Doctrine\Common\Collections\Criteria;
use Doctrine\Persistence\ObjectRepository;

/**
 * @template TEntityClass of object
 * @implements ObjectRepository<TEntityClass>
 */
class EntityRepository implements ObjectRepository
{

	/** @var class-string<TEntityClass> */
	protected $_entityName;

	/**
	 * @phpstan-param mixed $id
	 * @phpstan-param int|null $lockMode
	 * @phpstan-param int|null $lockVersion
	 * @phpstan-return TEntityClass|null
	 * @phpstan-impure
	 */
	public function find($id, $lockMode = null, $lockVersion = null);

	/**
	 * @phpstan-return list<TEntityClass>
	 * @phpstan-impure
	 */
	public function findAll();

	/**
	 * @phpstan-param array<string, mixed> $criteria
	 * @phpstan-param array<string, string>|null $orderBy
	 * @phpstan-param int|null $limit
	 * @phpstan-param int|null $offset
	 * @phpstan-return list<TEntityClass>
	 * @phpstan-impure
	 */
	public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);

	/**
	 * @phpstan-param array<string, mixed> $criteria The criteria.
	 * @phpstan-param array<string, string>|null $orderBy
	 * @phpstan-return TEntityClass|null
	 * @phpstan-impure
	 */
	public function findOneBy(array $criteria, ?array $orderBy = null);

	/**
	 * @phpstan-return class-string<TEntityClass>
	 */
	public function getClassName();

	/**
	 * @phpstan-return class-string<TEntityClass>
	 */
	protected function getEntityName();

	/**
	 * @param \Doctrine\Common\Collections\Criteria $criteria
	 *
	 * @return \Doctrine\Common\Collections\Collection
	 *
	 * @psalm-return \Doctrine\Common\Collections\Collection<int, TEntityClass>
	 */
	public function matching(Criteria $criteria);

	/**
	 * @param __doctrine-literal-string      $alias
	 * @param __doctrine-literal-string|null $indexBy
	 *
	 * @return QueryBuilder
	 */
	public function createQueryBuilder($alias, $indexBy = null);

	/**
	 * @param array<string, mixed> $criteria
	 *
	 * @return int<0, max>
	 *
	 * @phpstan-impure
	 */
	public function count(array $criteria);

}
