package io.delphiplatform.api.v3.rdb.service.specification;

import org.springframework.data.jpa.domain.Specification;

import java.util.Collection;
import java.util.List;

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

import io.delphiplatform.api.util.CollectionUtils;
import io.delphiplatform.api.v3.rdb.service.dto.JpaPropertyPath;

public class FetchSpecification<T> implements Specification<T> {

    private final Collection<JpaPropertyPath> fetchPaths;
    private final boolean doDistinct;

    public FetchSpecification(Collection<JpaPropertyPath> fetchPaths, boolean doDistinct) {
        this.fetchPaths = fetchPaths;
        this.doDistinct = doDistinct;
    }

    @Override
    public Predicate toPredicate(Root<T> r, CriteriaQuery<?> cq, CriteriaBuilder cb) {
        if (cq.getResultType() != Long.class && !CollectionUtils.isEmpty(fetchPaths)) {
            fetchPaths.forEach(fetchPath -> {
                List<String> joins = fetchPath.getJoins();
                FetchParent<T, T> fetch = r;
                for (String join : joins) {
                    fetch = fetch.fetch(join, JoinType.LEFT);
                }
            });

            cq.distinct(doDistinct);
        }
        return null;
    }
}
