<commit_before><?php

namespace eCamp\Core\EntityService;

use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\Expr;
use eCamp\Core\Entity\Camp;
use eCamp\Core\Entity\CampCollaboration;
use eCamp\Core\Entity\User;
use eCamp\Core\Hydrator\CampCollaborationHydrator;
use eCamp\Core\Service\SendmailService;
use eCamp\Lib\Acl\Acl;
use eCamp\Lib\Entity\BaseEntity;
use eCamp\Lib\Service\EntityValidationException;
use eCamp\Lib\Service\ServiceUtils;
use Laminas\ApiTools\ApiProblem\ApiProblem;
use Laminas\Authentication\AuthenticationService;

class CampCollaborationService extends AbstractEntityService {
    private SendmailService $sendmailService;

    public function __construct(
        ServiceUtils $serviceUtils,
        AuthenticationService $authenticationService,
        SendmailService $sendmailService
    ) {
        parent::__construct(
            $serviceUtils,
            CampCollaboration::class,
            CampCollaborationHydrator::class,
            $authenticationService
        );
        $this->sendmailService = $sendmailService;
    }

    /**
     * @param mixed $data
     *
     * @throws ORMException
     * @throws \Exception
     *
     * @return ApiProblem|CampCollaboration
     */
    protected function createEntity($data) {
        $this->assertAuthenticated();

        $authUser = $this->getAuthUser();
        if (!isset($data->userId)) {
            $data->userId = null;
        }
        if (null == $data->userId && !$data->inviteEmail) {
            $data->userId = $authUser->getId();
        }

        /** @var Camp $camp */
        $camp = $this->findRelatedEntity(Camp::class, $data, 'campId');

        /** @var User $user */
        $user = null != $data->userId ? $this->findRelatedEntity(User::class, $data, 'userId') : null;

        $q = $this->fetchAllQueryBuilder();
        $expr = new Expr();
        $q->andWhere($expr->andX(
            $q->expr()->eq('row.camp', ':campId'),
            $expr->orX(
                $expr->eq('row.user', ':userId'),
                $expr->eq('row.inviteEmail', ':inviteEmail')
            )
        ));
        $q->setParameter('campId', $camp->getId());
        $q->setParameter('userId', null != $user ? $user->getId() : null);
        $q->setParameter('inviteEmail', $data->inviteEmail);
        $result = $q->getQuery()->getResult();

        if (count($result) > 0) {
            $messages = [];
            if ($data->userId) {
                $messages['userId'] = ['duplicateCampCollaboration' => "CampCollaboration for the camp {$data->campId} and user {$data->userId} already exists."];
            }
            if ($data->inviteEmail) {
                $messages['inviteEmail'] = ['duplicateCampCollaboration' => "CampCollaboration for the camp {$data->campId} and inviteEmail {$data->inviteEmail} already exists."];
            }

            throw (new EntityValidationException())->setMessages($messages);
        }
        /** @var CampCollaboration $campCollaboration */
        $campCollaboration = parent::createEntity($data);
        $camp->addCampCollaboration($campCollaboration);
        if (null != $user) {
            $user->addCampCollaboration($campCollaboration);
        }

        if (!isset($data->role)) {
            $data->role = CampCollaboration::ROLE_MEMBER;
        }
        $campCollaboration->setRole($data->role);

        $this->assertAllowed($campCollaboration, Acl::REST_PRIVILEGE_CREATE);

        if ($data->userId === $authUser->getId()) {
            if ($data->userId === $camp->getCreator()->getId()) {
                // Create CampCollaboration for Creator
                $campCollaboration->setStatus(CampCollaboration::STATUS_ESTABLISHED);
                $campCollaboration->setCollaborationAcceptedBy($authUser->getUsername());
            } else {
                // Create CampCollaboration for AuthUser
                $campCollaboration->setStatus(CampCollaboration::STATUS_REQUESTED);
            }
        } else {
            // Create CampCollaboration for other User
            $campCollaboration->setStatus(CampCollaboration::STATUS_INVITED);
            $campCollaboration->setCollaborationAcceptedBy($authUser->getUsername());
            $campCollaboration->setInviteEmail($data->inviteEmail);
        }

        if (CampCollaboration::STATUS_INVITED == $campCollaboration->getStatus() && $campCollaboration->getInviteEmail()) {
            $uniqid = uniqid('', true);
            $campCollaboration->setInviteKey($uniqid);
            $this->sendmailService->sendInviteToCampMail(
                $authUser,
                $camp,
                $uniqid,
                $campCollaboration->getInviteEmail()
            );
        }

        return $campCollaboration;
    }

    /**
     * @param $data
     *<commit_msg>CampCollaborationService: fix test<commit_after><?php

namespace eCamp\Core\EntityService;

use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\Expr;
use eCamp\Core\Entity\Camp;
use eCamp\Core\Entity\CampCollaboration;
use eCamp\Core\Entity\User;
use eCamp\Core\Hydrator\CampCollaborationHydrator;
use eCamp\Core\Service\SendmailService;
use eCamp\Lib\Acl\Acl;
use eCamp\Lib\Entity\BaseEntity;
use eCamp\Lib\Service\EntityValidationException;
use eCamp\Lib\Service\ServiceUtils;
use Laminas\ApiTools\ApiProblem\ApiProblem;
use Laminas\Authentication\AuthenticationService;

class CampCollaborationService extends AbstractEntityService {
    private SendmailService $sendmailService;

    public function __construct(
        ServiceUtils $serviceUtils,
        AuthenticationService $authenticationService,
        SendmailService $sendmailService
    ) {
        parent::__construct(
            $serviceUtils,
            CampCollaboration::class,
            CampCollaborationHydrator::class,
            $authenticationService
        );
        $this->sendmailService = $sendmailService;
    }

    /**
     * @param mixed $data
     *
     * @throws ORMException
     * @throws \Exception
     *
     * @return ApiProblem|CampCollaboration
     */
    protected function createEntity($data) {
        $this->assertAuthenticated();

        $authUser = $this->getAuthUser();
        if (!isset($data->userId)) {
            $data->userId = null;
        }
        $inviteEmail = isset($data->inviteEmail) ? $data->inviteEmail : null;
        if (null == $data->userId && !$inviteEmail) {
            $data->userId = $authUser->getId();
        }

        /** @var Camp $camp */
        $camp = $this->findRelatedEntity(Camp::class, $data, 'campId');

        /** @var User $user */
        $user = null != $data->userId ? $this->findRelatedEntity(User::class, $data, 'userId') : null;

        $q = $this->fetchAllQueryBuilder();
        $expr = new Expr();
        $q->andWhere($expr->andX(
            $q->expr()->eq('row.camp', ':campId'),
            $expr->orX(
                $expr->eq('row.user', ':userId'),
                $expr->eq('row.inviteEmail', ':inviteEmail')
            )
        ));
        $q->setParameter('campId', $camp->getId());
        $q->setParameter('userId', null != $user ? $user->getId() : null);
        $q->setParameter('inviteEmail', $inviteEmail);
        $result = $q->getQuery()->getResult();

        if (count($result) > 0) {
            $messages = [];
            $userId = isset($data->userId) ? $data->userId : null;
            if ($userId) {
                $messages['userId'] = ['duplicateCampCollaboration' => "CampCollaboration for the camp {$data->campId} and user {$userId} already exists."];
            }
            if ($inviteEmail) {
                $messages['inviteEmail'] = ['duplicateCampCollaboration' => "CampCollaboration for the camp {$data->campId} and inviteEmail {$data->inviteEmail} already exists."];
            }

            throw (new EntityValidationException())->setMessages($messages);
        }
        /** @var CampCollaboration $campCollaboration */
        $campCollaboration = parent::createEntity($data);
        $camp->addCampCollaboration($campCollaboration);
        if (null != $user) {
            $user->addCampCollaboration($campCollaboration);
        }

        if (!isset($data->role)) {
            $data->role = CampCollaboration::ROLE_MEMBER;
        }
        $campCollaboration->setRole($data->role);

        $this->assertAllowed($campCollaboration, Acl::REST_PRIVILEGE_CREATE);

        if ($data->userId === $authUser->getId()) {
            if ($data->userId === $camp->getCreator()->getId()) {
                // Create CampCollaboration for Creator
                $campCollaboration->setStatus(CampCollaboration::STATUS_ESTABLISHED);
                $campCollaboration->setCollaborationAcceptedBy($authUser->getUsername());
            } else {
                // Create CampCollaboration for AuthUser
                $campCollaboration->setStatus(CampCollaboration::STATUS_REQUESTED);
            }
        } else {
            // Create CampCollaboration for other User
            $campCollaboration->setStatus(CampCollaboration::STATUS_INVITED);
            $campCollaboration->setCollaborationAcceptedBy($authUser->getUsername());
            $campCollaboration->setInviteEmail($inviteEmail);
        }

        if (CampCollaboration::STATUS_INVITED == $campCollaboration->getStatus() && $campCollaboration->getInviteEmail()) {
            $uniqid = uniqid('', true);
            $campCollaboration->setInviteKey($uniqid);
            $this->sendmailService->sendInviteToCampMail(
                $authUser,
                $camp,
                $uniqid,
                $campCollaboration->getInviteEmail()
            );
        }

        return $campCollaboration;
    }

    /**
     * @param $data
     *
{'fraction_non_alphanumeric': 0.13905447070914698, 'fraction_numerical': 0.00020554984583761563, 'mean_word_length': 2.4642221431114275, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 131, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4556770', 'n_tokens_mistral': 2808, 'n_tokens_neox': 2770, 'n_words': 438}