package cn.com.qmth.stmms.biz.exam.service.impl;

import java.util.LinkedList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.com.qmth.stmms.biz.common.BaseQueryService;
import cn.com.qmth.stmms.biz.exam.dao.ExamPackageDao;
import cn.com.qmth.stmms.biz.exam.model.ExamPackage;
import cn.com.qmth.stmms.biz.exam.query.ExamPackageSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.ExamPackageService;

@Service("examPackageService")
public class ExamPackageServiceImpl extends BaseQueryService<ExamPackage> implements ExamPackageService {

    @Autowired
    private ExamPackageDao packageDao;

    @Transactional
    @Override
    public ExamPackage save(ExamPackage examPackage) {
        return packageDao.save(examPackage);
    }

    @Override
    public ExamPackage find(int examId, String code) {
        return packageDao.findByExamIdAndCode(examId, code);
    }

    @Override
    public List<ExamPackage> list(int examId) {
        return packageDao.findByExamId(examId);
    }

    @Override
    public List<ExamPackage> list(int examId, boolean upload) {
        if (upload) {
            return packageDao.findByExamIdAndUpload(examId);
        } else {
            return packageDao.findByExamIdAndUnUpload(examId);
        }
    }

    @Override
    public ExamPackageSearchQuery findByQuery(ExamPackageSearchQuery query) {
        checkQuery(query);
        Page<ExamPackage> result = packageDao.findAll(buildSpecification(query), query);
        fillResult(result, query);
        return query;
    }

    @Override
    public long count(int examId) {
        return packageDao.countByExamId(examId);
    }

    @Override
    public long count(int examId, boolean upload) {
        if (upload) {
            return packageDao.countByExamIdAndUpload(examId);
        } else {
            return packageDao.countByExamIdAndUnUpload(examId);
        }
    }

    @Override
    public long countByQuery(ExamPackageSearchQuery query) {
        return packageDao.count(buildSpecification(query));
    }

    @Transactional
    @Override
    public void delete(ExamPackage examPackage) {
        packageDao.delete(examPackage);
    }

    @Transactional
    @Override
    public void deleteByExamId(int examId) {
        packageDao.deleteByExamId(examId);
    }

    private Specification<ExamPackage> buildSpecification(final ExamPackageSearchQuery query) {
        return new Specification<ExamPackage>() {

            @Override
            public Predicate toPredicate(Root<ExamPackage> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                List<Predicate> predicates = new LinkedList<Predicate>();
                if (query.getExamId() > 0) {
                    predicates.add(cb.equal(root.get("pk").get("examId"), query.getExamId()));
                }
                if (StringUtils.isNotEmpty(query.getCode())) {
                    predicates.add(cb.equal(root.get("pk").get("code"), query.getCode()));
                }
                if (query.getUpload() != null) {
                    if (query.getUpload().booleanValue()) {
                        predicates.add(cb.greaterThan(root.get("picCount").as(Integer.class), 0));
                    } else {
                        predicates.add(cb.equal(root.get("picCount"), 0));
                    }
                }
                return predicates.isEmpty() ? cb.conjunction() : cb.and(predicates.toArray(new Predicate[predicates
                        .size()]));
            }
        };
    }

}
