package lan.dk.podcastserver.repository.dsl;


import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import lan.dk.podcastserver.entity.QItem;
import lan.dk.podcastserver.entity.Status;
import lan.dk.podcastserver.entity.Tag;

import java.time.ZonedDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Stream;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static java.util.stream.Collectors.*;

/**
 * Created by kevin on 08/06/2014 for Podcast Server
 */
public class ItemDSL {

    private static final QItem Q_ITEM = QItem.item;

    private ItemDSL() {
        throw new AssertionError();
    }

    public static Predicate isDownloaded(Boolean downloaded) {
        if (isNull(downloaded)) return null;
        if (downloaded) return hasStatus(Status.FINISH);

        return Q_ITEM.status.isNull().or(hasStatus(Status.NOT_DOWNLOADED));
    }

    public static BooleanExpression isNewerThan(ZonedDateTime dateTime){
        return Q_ITEM.pubDate.gt(dateTime);
    }

    public static BooleanExpression hasBeenDownloadedBefore(ZonedDateTime dateTime) {
        return Q_ITEM.downloadDate.lt(dateTime);
    }

    public static BooleanExpression hasBeenDownloadedAfter(ZonedDateTime dateTime) { return Q_ITEM.downloadDate.gt(dateTime); }
    public static BooleanExpression hasBeenCreatedAfter(ZonedDateTime dateTime) { return Q_ITEM.creationDate.gt(dateTime); }

    public static BooleanExpression isOfType(String type) {
        return Q_ITEM.podcast.type.eq(type);
    }



    public static BooleanExpression hasToBeDeleted(Boolean deleted){
        if (deleted)
            return Q_ITEM.podcast.hasToBeDeleted.isTrue();

        return Q_ITEM.podcast.hasToBeDeleted.isFalse();

    }

    static BooleanExpression isInId(final javaslang.collection.List<UUID> ids){
        return Q_ITEM.id.in(ids.toJavaList());
    }

    private static Predicate isInTags(javaslang.collection.Set<Tag> tags) {
        List<Predicate> predicates = tags
                .map(Q_ITEM.podcast.tags::contains)
                .map(Predicate.class::cast)
                .toJavaList();

        return ExpressionUtils.allOf(predicates);
    }

    public static Predicate hasStatus(final Status... statuses) {
        return ExpressionUtils.anyOf(Stream.of(statuses)
                        .map(Q_ITEM.status::eq)
                        .collect(toList())
                );
    }

    public static BooleanExpression isInPodcast(UUID podcastId) {
        return Q_ITEM.podcast.id.eq(podcastId);
    }

    public static Predicate getSearchSpecifications(javaslang.collection.List<UUID> ids, javaslang.collection.Set<Tag> tags, Boolean downloaded) {
        return ExpressionUtils.allOf(
                nonNull(ids) ? isInId(ids) : null,
                isInTags(tags),
                nonNull(downloaded) ? downloaded ? hasStatus(Status.FINISH) : Q_ITEM.status.isNull().or(hasStatus(Status.FINISH).not()) : null
        );
    }

    public static BooleanExpression isInAnyWatchList() {
        return Q_ITEM.watchLists.isNotEmpty();
    }
}

@@ -184,16 +184,116 @@
 ession;%0A
+import javaslang.collection.List;%0Aimport javaslang.collection.Set;%0Aimport javaslang.control.Option;%0A
 import l
@@ -446,31 +446,8 @@
 me;%0A
-import java.util.List;%0A
 impo
@@ -542,49 +542,8 @@
 ll;%0A
-import static java.util.Objects.nonNull;%0A
 impo
@@ -580,17 +580,22 @@
 lectors.
-*
+toList
 ;%0A%0A/**%0A 
@@ -1933,37 +1933,16 @@
 d(final 
-javaslang.collection.
 List%3CUUI
@@ -2042,37 +2042,16 @@
 sInTags(
-javaslang.collection.
 Set%3CTag%3E
@@ -2071,37 +2071,37 @@
     
-List%3CPredicate%3E predicates = 
+return ExpressionUtils.allOf(
 tags
@@ -2230,58 +2230,8 @@
 st()
-;%0A%0A        return ExpressionUtils.allOf(predicates
 );%0A 
@@ -2653,66 +2653,24 @@
 ons(
-javaslang.collection.List%3CUUID%3E ids, javaslang.collection.
+List%3CUUID%3E ids, 
 Set%3C
@@ -2760,41 +2760,65 @@
     
-nonNull(ids) ? isInId(ids) :
+Option.of(ids).map(ItemDSL::isInId).getOrElse(() -%3E
  null
+)
 ,%0A  
@@ -2867,15 +2867,17 @@
     
-nonNull
+Option.of
 (dow
@@ -2888,20 +2888,39 @@
 ded)
- ? downloade
+%0A                    .map(d -%3E 
 d ? 
@@ -3007,15 +3007,52 @@
 t())
- :
+)%0A                    .getOrElse(() -%3E
  null
+)
 %0A   

use import and option instead of ternary for null value