<commit_before><?php
/**
 * Created by PhpStorm.
 * User: stas
 * Date: 09.04.16
 * Time: 11:54
 */

namespace CoreBundle\Handler;

use CoreBundle\Entity\Game;
use CoreBundle\Entity\Tournament;
use CoreBundle\Entity\TournamentGame;
use CoreBundle\Entity\TournamentPlayer;
use CoreBundle\Entity\User;
use CoreBundle\Exception\Handler\Tournament\TournamentGameNotFoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentGameShouldBeSkippedException;
use CoreBundle\Exception\Handler\Tournament\TournamentMissRoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentNotFoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentPlayerNotFoundException;
use CoreBundle\Model\Event\Game\GameEvent;
use CoreBundle\Model\Event\Game\GameEvents;
use CoreBundle\Model\Event\Tournament\TournamentContainer;
use CoreBundle\Model\Event\Tournament\TournamentEvents;
use CoreBundle\Model\Event\Tournament\TournamentInitializator;
use CoreBundle\Model\Game\GameColor;
use CoreBundle\Model\Game\GameParams;
use CoreBundle\Model\Game\GameStatus;
use CoreBundle\Model\Request\Call\ErrorAwareTrait;
use CoreBundle\Model\Request\Tournament\TournamentDeleteUnrecordRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetCurrentgameRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetListRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetRequest;
use CoreBundle\Model\Request\Tournament\TournamentPostRecordRequest;
use CoreBundle\Model\Response\ResponseStatusCode;
use CoreBundle\Model\Tournament\Params\TournamentParamsFactory;
use CoreBundle\Model\Tournament\TournamentStatus;
use CoreBundle\Model\Tournament\TournamentType;
use CoreBundle\Processor\TournamentProcessorInterface;
use CoreBundle\Repository\TournamentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class TournamentHandler
 * @package CoreBundle\Handler
 */
class TournamentHandler implements TournamentProcessorInterface, EventSubscriberInterface
{
    use ContainerAwareTrait;
    use ErrorAwareTrait;

    /**
     * @var EntityManager
     */
    private $manager;

    /**
     * @var TournamentRepository
     */
    private $repository;

    /**
     * UserHandler constructor.
     * @param EntityManager $manager
     */
    public function __construct(EntityManager $manager)
    {
        $this->manager = $manager;
        $this->repository = $this->manager->getRepository('CoreBundle:Tournament');
    }

    /**
     * @return TournamentRepository
     */
    public function getRepository() : TournamentRepository
    {
        return $this->repository;
    }
    
    /**
     * @param TournamentGetListRequest $request
     * @return Tournament[]
     */
    public function processGetList(TournamentGetListRequest $request) : array
    {
        $tournaments = $this->repository
            ->findBy(['status' => $request->getStatus()], ['id' => 'DESC'], $request->getLimit());

        if ($request->getToken()) {
            $user = $this->container->get("core.service.security")->getUserIfCredentialsIsOk(
                $request,
                $this->getRequestError()
            );

            foreach ($tournaments as $tournament) {
                $tournament->setGames(new ArrayCollection());
                $tournament->setPlayers(new ArrayCollection());
                $this->setMineToTournament($tournament, $user);
            }
        }

        return $tournaments;
    }

    /**
     * @param TournamentGetRequest $request
     * @return Tournament
     */
    public function processGet(TournamentGetRequest $request) : Tournament
    {
        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                 ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        $this->container->get("core.service.tournament_table.factory")
             ->create($tournament->getTournamentParams()->getType())
             ->mixTournamentTable($tournament);

        try {
            $this->setMineToTournament(
                $tournament,
                $this->container->get("core.handler.user")->getSecureUser($request)
            );
        } catch (\Exception $e) {
            // it's ok
        }

        return $tournament;
    }

    /**
     * @param TournamentGetCurrentgameRequest $request
     * @return Game
     */
    public function processGetCurrentgame(TournamentGetCurrentgameRequest $request) : Game
    {
        $me = $this->container->get("core.service.security")->getUserIfCredentialsIsOk($request, $this->getRequestError());

        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        try {
            $this->searchTournamentPlayer($tournament, $me);
        } catch (TournamentPlayerNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "This is not your tournament")->throwException(ResponseStatusCode::FORBIDDEN);
        }

        try {
            $game = $this->getGameForCurrentRound($tournament, $me);
        } catch (TournamentMissRoundException $e) {
            $this->getRequestError()->addError("tournament_id", "You miss this round")->throwException(ResponseStatusCode::FORBIDDEN);
        }

        /** @var Game $game */
        return $game;
    }

    /**
     * @param TournamentPostRecordRequest $request
     * @return Tournament
     */
    public function processPostRecord(TournamentPostRecordRequest $request) : Tournament
    {
        $user = $this->container->get("core.handler.user")->getSecureUser($request);

        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                                    ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        if ($tournament->isPrivate()) {
            $this->getRequestError()->addError("login", "This is private tournament")
                ->throwException(ResponseStatusCode::FORBIDDEN);
        }

        if ($tournament->getStatus() != TournamentStatus::NEW()) {
            $this->getRequestError()->addError("login", "Tournament has already been started")
                 ->throwException(ResponseStatusCode::FORBIDDEN);
        }

        if ($user->getLag() > $this->container->getParameter("max_lag_for_record")) {
//            $this->getRequestError()->addError("login", "Your lag is too big")
//                ->throwException(ResponseStatusCode::FORBIDDEN);
        }
        
        /** @var Tournament $tournament */
        $tournament->addPlayer($user);

        $this->manager->persist($tournament);
        $this->manager->flush();

        $this->setMineToTournament($tournament, $user);

        return $tournament;
    }

    /**
     * @param TournamentDeleteUnrecordRequest $unrecordRequest
     * @return Tournament
     */
    public function processDeleteUnrecord(TournamentDeleteUnrecordRequest $unrecordRequest) : Tournament
    {
        $user = $this->container->get("core.service.security")->getUserIfCredentialsIsOk(<commit_msg>Deny tournament record for banned<commit_after><?php
/**
 * Created by PhpStorm.
 * User: stas
 * Date: 09.04.16
 * Time: 11:54
 */

namespace CoreBundle\Handler;

use CoreBundle\Entity\Game;
use CoreBundle\Entity\Tournament;
use CoreBundle\Entity\TournamentGame;
use CoreBundle\Entity\TournamentPlayer;
use CoreBundle\Entity\User;
use CoreBundle\Exception\Handler\Tournament\TournamentGameNotFoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentGameShouldBeSkippedException;
use CoreBundle\Exception\Handler\Tournament\TournamentMissRoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentNotFoundException;
use CoreBundle\Exception\Handler\Tournament\TournamentPlayerNotFoundException;
use CoreBundle\Model\Event\Game\GameEvent;
use CoreBundle\Model\Event\Game\GameEvents;
use CoreBundle\Model\Event\Tournament\TournamentContainer;
use CoreBundle\Model\Event\Tournament\TournamentEvents;
use CoreBundle\Model\Event\Tournament\TournamentInitializator;
use CoreBundle\Model\Game\GameColor;
use CoreBundle\Model\Game\GameParams;
use CoreBundle\Model\Game\GameStatus;
use CoreBundle\Model\Request\Call\ErrorAwareTrait;
use CoreBundle\Model\Request\Tournament\TournamentDeleteUnrecordRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetCurrentgameRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetListRequest;
use CoreBundle\Model\Request\Tournament\TournamentGetRequest;
use CoreBundle\Model\Request\Tournament\TournamentPostRecordRequest;
use CoreBundle\Model\Response\ResponseStatusCode;
use CoreBundle\Model\Tournament\Params\TournamentParamsFactory;
use CoreBundle\Model\Tournament\TournamentStatus;
use CoreBundle\Model\Tournament\TournamentType;
use CoreBundle\Processor\TournamentProcessorInterface;
use CoreBundle\Repository\TournamentRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManager;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Class TournamentHandler
 * @package CoreBundle\Handler
 */
class TournamentHandler implements TournamentProcessorInterface, EventSubscriberInterface
{
    use ContainerAwareTrait;
    use ErrorAwareTrait;

    /**
     * @var EntityManager
     */
    private $manager;

    /**
     * @var TournamentRepository
     */
    private $repository;

    /**
     * UserHandler constructor.
     * @param EntityManager $manager
     */
    public function __construct(EntityManager $manager)
    {
        $this->manager = $manager;
        $this->repository = $this->manager->getRepository('CoreBundle:Tournament');
    }

    /**
     * @return TournamentRepository
     */
    public function getRepository() : TournamentRepository
    {
        return $this->repository;
    }
    
    /**
     * @param TournamentGetListRequest $request
     * @return Tournament[]
     */
    public function processGetList(TournamentGetListRequest $request) : array
    {
        $tournaments = $this->repository
            ->findBy(['status' => $request->getStatus()], ['id' => 'DESC'], $request->getLimit());

        if ($request->getToken()) {
            $user = $this->container->get("core.service.security")->getUserIfCredentialsIsOk(
                $request,
                $this->getRequestError()
            );

            foreach ($tournaments as $tournament) {
                $tournament->setGames(new ArrayCollection());
                $tournament->setPlayers(new ArrayCollection());
                $this->setMineToTournament($tournament, $user);
            }
        }

        return $tournaments;
    }

    /**
     * @param TournamentGetRequest $request
     * @return Tournament
     */
    public function processGet(TournamentGetRequest $request) : Tournament
    {
        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                 ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        $this->container->get("core.service.tournament_table.factory")
             ->create($tournament->getTournamentParams()->getType())
             ->mixTournamentTable($tournament);

        try {
            $this->setMineToTournament(
                $tournament,
                $this->container->get("core.handler.user")->getSecureUser($request)
            );
        } catch (\Exception $e) {
            // it's ok
        }

        return $tournament;
    }

    /**
     * @param TournamentGetCurrentgameRequest $request
     * @return Game
     */
    public function processGetCurrentgame(TournamentGetCurrentgameRequest $request) : Game
    {
        $me = $this->container->get("core.service.security")->getUserIfCredentialsIsOk($request, $this->getRequestError());

        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        try {
            $this->searchTournamentPlayer($tournament, $me);
        } catch (TournamentPlayerNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "This is not your tournament")->throwException(ResponseStatusCode::FORBIDDEN);
        }

        try {
            $game = $this->getGameForCurrentRound($tournament, $me);
        } catch (TournamentMissRoundException $e) {
            $this->getRequestError()->addError("tournament_id", "You miss this round")->throwException(ResponseStatusCode::FORBIDDEN);
        }

        /** @var Game $game */
        return $game;
    }

    /**
     * @param TournamentPostRecordRequest $request
     * @return Tournament
     */
    public function processPostRecord(TournamentPostRecordRequest $request) : Tournament
    {
        $user = $this->container->get("core.handler.user")->getSecureUser($request);

        try {
            $tournament = $this->repository->find($request->getTournamentId());
        } catch (TournamentNotFoundException $e) {
            $this->getRequestError()->addError("tournament_id", "Tournament is not found")
                                    ->throwException(ResponseStatusCode::NOT_FOUND);
        }

        /** @var Tournament $tournament */
        if ($tournament->isPrivate()) {
            $this->getRequestError()->addError("login", "This is private tournament")
                ->throwException(ResponseStatusCode::FORBIDDEN);
        }

        if ($tournament->getStatus() != TournamentStatus::NEW()) {
            $this->getRequestError()->addError("login", "Tournament has already been started")
                 ->throwException(ResponseStatusCode::FORBIDDEN);
        }

        if ($user->getLag() > $this->container->getParameter("max_lag_for_record")) {
//            $this->getRequestError()->addError("login", "Your lag is too big")
//                ->throwException(ResponseStatusCode::FORBIDDEN);
        }

        if ($user->isBanned()) {
            $this->getRequestError()->addError("login", "You are banned")
                ->throwException(ResponseStatusCode::FORBIDDEN);
        }
        
        /** @var Tournament $tournament */
        $tournament->addPlayer($user);

        $this->manager->persist($tournament);
        $this->manager->flush();

        $this->setMineToTournament($tournament, $user);

        return $tournament;
    }

    /**
     * @param TournamentDeleteUnrecordRequest $unrecordRequest
     * @return Tournament
     */
    public function processDeleteUnrecord(TournamentDeleteUnrecordRequest $unrecordRequest) : Tournament
    {
        $user = $this->container->get("core.service.security")->getUserIfCredentialsIsOk(
{'fraction_non_alphanumeric': 0.12195892575039495, 'fraction_numerical': 0.001263823064770932, 'mean_word_length': 3.1138549519105796, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5441375', 'n_tokens_mistral': 4450, 'n_tokens_neox': 4140, 'n_words': 670}