package com.box.l10n.mojito.rest.repository;

import com.box.l10n.mojito.entity.Branch;
import com.box.l10n.mojito.entity.BranchStatistic;
import com.box.l10n.mojito.entity.BranchStatistic_;
import com.box.l10n.mojito.entity.Branch_;
import com.box.l10n.mojito.entity.security.user.User;
import com.box.l10n.mojito.entity.security.user.User_;
import com.box.l10n.mojito.specification.SingleParamSpecification;

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

/**
 * @author jeanaurambault
 */
public class BranchStatisticSpecification {

    public static SingleParamSpecification<BranchStatistic> branchEquals(final Long branchId) {
        return new SingleParamSpecification<BranchStatistic>(branchId) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                return builder.equal(root.get(BranchStatistic_.branch), branchId);
            }
        };
    }

    public static SingleParamSpecification<BranchStatistic> branchNameEquals(final String branchName) {
        return new SingleParamSpecification<BranchStatistic>(branchName) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                Join<BranchStatistic, Branch> branchJoin = root.join(BranchStatistic_.branch, JoinType.LEFT);
                return builder.equal(branchJoin.get(Branch_.name), branchName);
            }
        };
    }

    public static SingleParamSpecification<BranchStatistic> search(final String search) {
        return new SingleParamSpecification<BranchStatistic>(search) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                Join<BranchStatistic, Branch> branchJoin = root.join(BranchStatistic_.branch, JoinType.LEFT);
                Join<Branch, User> userJoin = branchJoin.join(Branch_.createdByUser, JoinType.LEFT);

                String ilikeSearch = search.toLowerCase();

                return builder.or(
                        builder.like(builder.lower(branchJoin.get(Branch_.name)), ilikeSearch),
                        builder.like(builder.lower(userJoin.get(User_.username)), ilikeSearch)
                );
            }
        };
    }

    public static SingleParamSpecification<BranchStatistic> createdByUserNameEquals(final String createdByUserName) {
        return new SingleParamSpecification<BranchStatistic>(createdByUserName) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                Join<BranchStatistic, Branch> branchJoin = root.join(BranchStatistic_.branch, JoinType.LEFT);
                Join<Branch, User> userJoin = branchJoin.join(Branch_.createdByUser, JoinType.LEFT);
                return builder.equal(userJoin.get(User_.username), createdByUserName);
            }
        };
    }

    public static SingleParamSpecification<BranchStatistic> deletedEquals(final Boolean deleted) {
        return new SingleParamSpecification<BranchStatistic>(deleted) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                Join<BranchStatistic, Branch> branchJoin = root.join(BranchStatistic_.branch, JoinType.LEFT);
                return builder.equal(branchJoin.get(Branch_.deleted), deleted);
            }
        };
    }

    public static SingleParamSpecification<BranchStatistic> empty(final boolean empty) {
        return new SingleParamSpecification<BranchStatistic>(empty) {
            @Override
            public Predicate toPredicate(Root<BranchStatistic> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                Predicate predicate = builder.equal(root.get(BranchStatistic_.totalCount), 0L);
                if (!empty) {
                    predicate = builder.not(predicate);
                }
                return predicate;
            }
        };
    }
}

@@ -3773,32 +3773,144 @@
       %7D;%0A    %7D%0A%0A
+    /**%0A     *%0A     * @param empty if %7B@code null%7D, will behave as %7B@link Boolean#FALSE%7D%0A     * @return%0A     */%0A
     public stati
@@ -3965,17 +3965,17 @@
 y(final 
-b
+B
 oolean e
@@ -3974,32 +3974,33 @@
 oolean empty) %7B%0A
+%0A
         return n
@@ -4215,29 +4215,63 @@
     
-P
 re
-dicate predicate =
+turn empty != null && empty%0A                        ?
  bui
@@ -4323,17 +4323,16 @@
 nt), 0L)
-;
 %0A       
@@ -4344,128 +4344,77 @@
     
-if (!empty) %7B%0A                    predicate = builder.not(predicate);%0A                %7D%0A                return predicate
+        : builder.notEqual(root.get(BranchStatistic_.totalCount), 0L)
 ;%0A  

Fix NPE when getting all branches (#508)