package com.atlassian.stash.internal.commit;

import com.atlassian.stash.internal.participant.AbstractHibernateParticipantDao;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.annotation.Nonnull;

import java.util.Collections;

import static com.atlassian.stash.internal.HibernateUtils.initialize;
import static com.atlassian.stash.internal.HibernateUtils.initializePage;

/**
 * @since 2.11
 */
@Repository("commitDiscussionParticipantDao")
public class HibernateCommitDiscussionParticipantDao
        extends AbstractHibernateParticipantDao<InternalCommitDiscussionParticipant>
        implements CommitDiscussionParticipantDao {

    @Autowired
    public HibernateCommitDiscussionParticipantDao(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

    @Nonnull
    @Override
    public Page<InternalCommitDiscussionParticipant> findByDiscussion(long discussionId,
                                                                      @Nonnull PageRequest pageRequest) {
        Criteria criteria = session().createCriteria(InternalCommitDiscussionParticipant.class)
                .add(Restrictions.eq("discussion.id", discussionId));

        return initializePage(pageCriteria(applyImplicitOrder(criteria), pageRequest));
    }

    @Override
    public InternalCommitDiscussionParticipant findByDiscussionAndUser(long discussionId, int userId) {
        Criteria criteria = session().createCriteria(InternalCommitDiscussionParticipant.class)
                .add(Restrictions.eq("discussion.id", discussionId))
                .add(Restrictions.eq("user.id", userId));

        return initialize((InternalCommitDiscussionParticipant) criteria.uniqueResult());
    }

    @Nonnull
    @Override
    public InternalCommitDiscussionParticipant update(@Nonnull InternalCommitDiscussionParticipant participant) {
        throw new UnsupportedOperationException("CommitDiscussionParticipants are immutable and cannot be updated.");
    }

    @Override
    protected Iterable<Order> getImplicitOrder() {
        return Collections.singleton(Order.asc("id"));
    }
}
