package io.teiler.server.persistence.repositories;

import com.querydsl.jpa.impl.JPAQuery;
import io.teiler.server.dto.Person;
import io.teiler.server.persistence.entities.GroupEntity;
import io.teiler.server.persistence.entities.PersonEntity;
import io.teiler.server.persistence.entities.QPersonEntity;
import java.util.List;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * Provides database-related operations for Groups.
 *
 * @author lroellin
 * @author pbaechli
 */
@Repository
public class PersonRepository {

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private GroupRepository groupRepository;

    /**
     * Creates a new Person and returns it.
     *
     * @param groupId Id of the Group
     * @param person Name of the Group
     * @return {@link GroupEntity}
     */
    @Transactional
    public PersonEntity create(String groupId, Person person) {
        GroupEntity groupEntity = groupRepository.getGroupById(groupId);
        PersonEntity personEntity = new PersonEntity(person);
        groupEntity.addPerson(personEntity);
        entityManager.persist(personEntity);
        entityManager.persist(groupEntity);
        return personEntity;
    }

    /**
     * Returns a {@link PersonEntity} with the given name and Group-Id.
     *
     * @param groupId Id of the Group
     * @param name Name of the Person
     * @return {@link PersonEntity}
     */
    public PersonEntity getByName(String groupId, String name) {
        return new JPAQuery<PersonEntity>(entityManager).from(QPersonEntity.personEntity)
            .where(QPersonEntity.personEntity.groupId.eq(groupId)
                .and(QPersonEntity.personEntity.name.eq(name)))
            .fetchOne();
    }

    /**
     * Returns a {@link List} of {@link PersonEntity} in the Group with the given Id.
     *
     * @param groupId Id of the Group
     * @param limit Maximum amount of people to fetch
     * @return {@link List} of {@link PersonEntity}
     */
    public List<PersonEntity> getPeople(String groupId, long limit) {
        return new JPAQuery<PersonEntity>(entityManager).from(QPersonEntity.personEntity)
            .where(QPersonEntity.personEntity.groupId.eq(groupId))
            .limit(limit)
            .orderBy(QPersonEntity.personEntity.id.asc())
            .fetch();
    }

    /**
     * Returns a {@link PersonEntity} with the given Group- and Person-Id.
     *
     * @param groupId Id of the Group
     * @param personId Id of the Person
     * @return {@link PersonEntity}
     */
    public PersonEntity getByGroupAndPersonId(String groupId, int personId) {
        return new JPAQuery<PersonEntity>(entityManager).from(QPersonEntity.personEntity)
            .where(QPersonEntity.personEntity.groupId.eq(groupId)
                .and(QPersonEntity.personEntity.id.eq(personId)))
            .fetchOne();
    }

    /**
     * Returns the {@link PersonEntity} with the given Id.
     *
     * @param personId Id of the Person
     * @return {@link PersonEntity}
     */
    public PersonEntity getById(int personId) {
        return new JPAQuery<PersonEntity>(entityManager).from(QPersonEntity.personEntity)
            .where(QPersonEntity.personEntity.id.eq(personId))
            .fetchOne();
    }

    /**
     * Updates a already persisted Person with the given values.
     *
     * @param personId Id of the Person
     * @param changedPerson {@link Person} containing the new values
     * @return {@link PersonEntity} containing the new values
     */
    @Transactional
    public PersonEntity editPerson(int personId, Person changedPerson) {
        PersonEntity existingPerson = getById(personId);

        PersonEntity updatedPerson = new PersonEntity(changedPerson);
        updatedPerson.setId(existingPerson.getId());
        updatedPerson.setGroupId(existingPerson.getGroupId());

        return entityManager.merge(updatedPerson);
    }

    /**
     * Deletes the Person with the given Id.
     *
     * @param personId Id of the Person
     */
    @Transactional
    public void deletePerson(int personId) {
        PersonEntity person = getById(personId);
        entityManager.remove(person);
    }

}

@@ -49,260 +49,8 @@
 s;%0A%0A
-import com.querydsl.jpa.impl.JPAQuery;%0Aimport io.teiler.server.dto.Person;%0Aimport io.teiler.server.persistence.entities.GroupEntity;%0Aimport io.teiler.server.persistence.entities.PersonEntity;%0Aimport io.teiler.server.persistence.entities.QPersonEntity;%0A
 impo
@@ -68,16 +68,17 @@
 l.List;%0A
+%0A
 import j
@@ -149,16 +149,17 @@
 tional;%0A
+%0A
 import o
@@ -213,16 +213,16 @@
 owired;%0A
-
 import o
@@ -264,16 +264,270 @@
 itory;%0A%0A
+import com.querydsl.jpa.impl.JPAQuery;%0A%0Aimport io.teiler.server.dto.Person;%0Aimport io.teiler.server.persistence.entities.GroupEntity;%0Aimport io.teiler.server.persistence.entities.PersonEntity;%0Aimport io.teiler.server.persistence.entities.QPersonEntity;%0A%0A
 /**%0A * P
@@ -4061,272 +4061,6 @@
  %7D%0A%0A
-    /**%0A     * Deletes the Person with the given Id.%0A     *%0A     * @param personId Id of the Person%0A     */%0A    @Transactional%0A    public void deletePerson(int personId) %7B%0A        PersonEntity person = getById(personId);%0A        entityManager.remove(person);%0A    %7D%0A%0A
 %7D%0A

remove uncovered and unused method