package org.iatoki.judgels.uriel.services.impls;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.iatoki.judgels.play.IdentityUtils;
import org.iatoki.judgels.play.JidService;
import org.iatoki.judgels.play.Page;
import org.iatoki.judgels.uriel.ContestClarification;
import org.iatoki.judgels.uriel.ContestClarificationNotFoundException;
import org.iatoki.judgels.uriel.ContestClarificationStatus;
import org.iatoki.judgels.uriel.ContestReadType;
import org.iatoki.judgels.uriel.models.daos.ContestClarificationDao;
import org.iatoki.judgels.uriel.models.daos.ContestDao;
import org.iatoki.judgels.uriel.models.daos.ContestProblemDao;
import org.iatoki.judgels.uriel.models.daos.ContestReadDao;
import org.iatoki.judgels.uriel.models.entities.ContestClarificationModel;
import org.iatoki.judgels.uriel.models.entities.ContestClarificationModel_;
import org.iatoki.judgels.uriel.models.entities.ContestModel;
import org.iatoki.judgels.uriel.models.entities.ContestProblemModel;
import org.iatoki.judgels.uriel.models.entities.ContestReadModel;
import org.iatoki.judgels.uriel.services.ContestClarificationService;
import play.i18n.Messages;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.persistence.metamodel.SingularAttribute;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Singleton
@Named("contestClarificationService")
public final class ContestClarificationServiceImpl implements ContestClarificationService {
private final ContestDao contestDao;
private final ContestProblemDao contestProblemDao;
private final ContestClarificationDao contestClarificationDao;
private final ContestReadDao contestReadDao;
@Inject
public ContestClarificationServiceImpl(ContestDao contestDao, ContestProblemDao contestProblemDao, ContestClarificationDao contestClarificationDao, ContestReadDao contestReadDao) {
this.contestDao = contestDao;
this.contestProblemDao = contestProblemDao;
this.contestClarificationDao = contestClarificationDao;
this.contestReadDao = contestReadDao;
}
@Override
public ContestClarification findContestClarificationByContestClarificationId(long contestClarificationId) throws ContestClarificationNotFoundException {
ContestClarificationModel contestClarificationModel = contestClarificationDao.findById(contestClarificationId);
if (contestClarificationModel != null) {
ContestModel contestModel = contestDao.findByJid(contestClarificationModel.contestJid);
return createContestClarificationFromModel(contestClarificationModel, contestModel);
} else {
throw new ContestClarificationNotFoundException("Contest Clarification not found.");
}
}
@Override
public Page<ContestClarification> pageContestClarificationsByContestJid(String contestJid, long pageIndex, long pageSize, String orderBy, String orderDir, String filterString, List<String> askerJids) {
ContestModel contestModel = contestDao.findByJid(contestJid);
if (askerJids == null) {
ImmutableMap.Builder<SingularAttribute<? super ContestClarificationModel, String>, String> filterColumnsBuilder = ImmutableMap.builder();
filterColumnsBuilder.put(ContestClarificationModel_.contestJid, contestJid);
Map<SingularAttribute<? super ContestClarificationModel, String>, String> filterColumns = filterColumnsBuilder.build();
long totalPages = contestClarificationDao.countByFilters(filterString, filterColumns, ImmutableMap.of());
List<ContestClarificationModel> contestClarificationModels = contestClarificationDao.findSortedByFilters(orderBy, orderDir, filterString, filterColumns, ImmutableMap.of(), pageIndex * pageSize, pageSize);
List<ContestClarification> contestClarifications = Lists.transform(contestClarificationModels, m -> createContestClarificationFromModel(m, contestModel));
return new Page<>(contestClarifications, totalPages, pageIndex, pageSize);
} else {
long totalPages = contestClarificationDao.countClarificationsByContestJidAskedByUserJids(contestModel.jid, askerJids);
List<ContestClarificationModel> contestClarificationModels = contestClarificationDao.findClarificationsByContestJidAskedByUserJids(contestModel.jid, askerJids);
List<ContestClarification> contestClarifications = Lists.transform(contestClarificationModels, m -> createContestClarificationFromModel(m, contestModel));
return new Page<>(contestClarifications, totalPages, pageIndex, pageSize);
}
}
@Override
public long getUnansweredContestClarificationsCount(String contestJid) {
return contestClarificationDao.countUnansweredClarificationByContestJid(contestJid);
}
@Override
public long getUnreadContestClarificationsCount(List<String> askerJids, String userJid, String contestJid, boolean answered) {
List<String> clarificationJids;
if (answered) {
clarificationJids = contestClarificationDao.findAllAnsweredClarificationJidsInContestByUserJids(contestJid, askerJids);
} else {
clarificationJids = contestClarificationDao.findClarificationJidsByContestJidAskedByUserJids(contestJid, askerJids);
}
if (!clarificationJids.isEmpty()) {
return (clarificationJids.size() - contestReadDao.countReadByUserJidAndTypeAndJidList(userJid, ContestReadType.CLARIFICATION.name(), clarificationJids));
} else {
return 0;
}
}
@Override
public void createContestClarification(long contestId, String title, String question, String topicJid) {
ContestModel contestModel = contestDao.findById(contestId);
ContestClarificationModel contestClarificationModel = new ContestClarificationModel();
contestClarificationModel.contestJid = contestModel.jid;
contestClarificationModel.title = title;
contestClarificationModel.question = question;
contestClarificationModel.topicJid = topicJid;
contestClarificationModel.status = ContestClarificationStatus.ASKED.name();
contestClarificationDao.persist(contestClarificationModel, IdentityUtils.getUserJid(), IdentityUtils.getIpAddress());
}
@Override
public void updateContestClarification(long contestClarificationId, String title, String question) {
ContestClarificationModel contestClarificationModel = contestClarificationDao.findById(contestClarificationId);
contestClarificationModel.title = title;
contestClarificationModel.question = question;
contestClarificationDao.edit(contestClarificationModel, IdentityUtils.getUserJid(), IdentityUtils.getIpAddress());
}
@Override
public void updateContestClarification(long contestClarificationId, String answer, ContestClarificationStatus status) {
ContestClarificationModel contestClarificationModel = contestClarificationDao.findById(contestClarificationId);
contestClarificationModel.answer = answer;
contestClarificationModel.status = status.name();
contestClarificationDao.edit(contestClarificationModel, IdentityUtils.getUserJid(), IdentityUtils.getIpAddress());
}
@Override
public void readContestClarifications(String userJid, List<String> contestClarificationJids) {
for (String contestClarificationJid : contestClarificationJids) {
if (!contestReadDao.existByUserJidAndTypeAndJid(userJid, ContestReadType.CLARIFICATION.name(), contestClarificationJid)) {
ContestReadModel contestReadModel = new ContestReadModel();
contestReadModel.userJid = userJid;
contestReadModel.type = ContestReadType.CLARIFICATION.name();
contestReadModel.readJid = contestClarificationJid;
contestReadDao.persist(contestReadModel, IdentityUtils.getUserJid(), IdentityUtils.getIpAddress());
}
}
}
private ContestClarification createContestClarificationFromModel(ContestClarificationModel contestClarificationModel, ContestModel contestModel) {
String topic;
if ("CONT".equals(JidService.getInstance().parsePrefix(contestClarificationModel.topicJid))) {
topic = "(" + Messages.get("clarification.general") + ")";
} else {
ContestProblemModel contestProblemModel = contestProblemDao.findByProblemJidOrderedByAlias(contestModel.jid, contestClarificationModel.topicJid);
topic = contestProblemModel.alias + " - " + JidCacheServiceImpl.getInstance().getDisplayName(contestProblemModel.problemJid);
}
return new ContestClarification(contestClarificationModel.id, contestClarificationModel.jid, contestClarificationModel.contestJid, topic, contestClarificationModel.title, contestClarificationModel.question, contestClarificationModel.answer, contestClarificationModel.userCreate, contestClarificationModel.userUpdate, ContestClarificationStatus.valueOf(contestClarificationModel.status), new Date(contestClarificationModel.timeCreate), new Date(contestClarificationModel.timeUpdate));
}
}