package lan.dk.podcastserver.repository.impl;

import lan.dk.podcastserver.entity.Item;
import lan.dk.podcastserver.repository.custom.ItemRepositoryCustom;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.CacheMode;
import org.hibernate.search.batchindexing.impl.SimpleIndexingProgressMonitor;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.query.dsl.BooleanJunction;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.hibernate.transform.ResultTransformer;
import org.springframework.beans.factory.annotation.Autowired;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Slf4j
public class ItemRepositoryImpl implements ItemRepositoryCustom {

    private static final String[] SEARCH_FIELDS = new String[]{"description", "title"};
    private static final HibernateIdExtractor RESULT_TRANSFORMER = new HibernateIdExtractor();

    final FullTextEntityManager fullTextEntityManager;

    @Autowired
    public ItemRepositoryImpl(FullTextEntityManager fem) {
        this.fullTextEntityManager = fem;
    }

    @Override
    public void reindex() throws InterruptedException {
        fullTextEntityManager
                .createIndexer(Item.class)
                .batchSizeToLoadObjects(25)
                .cacheMode(CacheMode.NORMAL)
                .idFetchSize(150)
                .threadsToLoadObjects(1)
                .progressMonitor(new SimpleIndexingProgressMonitor(1000))
                .startAndWait();
    }

    @Override
    @Transactional
    @SuppressWarnings("unchecked")
    public List<UUID> fullTextSearch(String term) {
        if (StringUtils.isEmpty(term))
            return new ArrayList<>();

        QueryBuilder qbDsl = fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder().forEntity(Item.class).get();

        final BooleanJunction<BooleanJunction> query = qbDsl.bool();
        Arrays.stream(term.split("\\s+"))
                .map(subTerm -> qbDsl.keyword().onFields(SEARCH_FIELDS).matching(subTerm).createQuery())
                .forEach(query::must);

        List<UUID> results = fullTextEntityManager.createFullTextQuery(query.createQuery(), Item.class)
                .setProjection("id")
                .setResultTransformer(RESULT_TRANSFORMER)
                .<UUID>getResultList();

        if (results == null) {
            return new ArrayList<>();
        }

        return results;
    }

    static class HibernateIdExtractor implements ResultTransformer {
        @Override
        public Object transformTuple(Object[] tuple, String[] aliases) {
            return tuple[0];
        }

        @Override
        public List transformList(List collection) {
            return collection;
        }
    }
}

@@ -40,16 +40,56 @@
 .impl;%0A%0A
+import com.google.common.collect.Lists;%0A
 import l
@@ -715,88 +715,9 @@
 til.
-ArrayList;%0Aimport java.util.Arrays;%0Aimport java.util.List;%0Aimport java.util.UUID
+*
 ;%0A%0A@
@@ -2176,29 +2176,35 @@
     
-List%3CUUID%3E results = 
+return Optional.ofNullable(
 full
@@ -2266,32 +2266,36 @@
 (), Item.class)%0A
+    
                 
@@ -2327,24 +2327,28 @@
             
+    
 .setResultTr
@@ -2393,16 +2393,20 @@
         
+    
 .%3CUUID%3Eg
@@ -2419,18 +2419,17 @@
 ltList()
-;%0A
+)
 %0A       
@@ -2433,54 +2433,37 @@
     
-if (results == null) %7B%0A            return 
+        .orElseGet(Lists::
 new
- 
 Arra
@@ -2471,47 +2471,9 @@
 List
-%3C%3E();%0A        %7D%0A%0A        return results
+)
 ;%0A  

refactor code about search by term