/*
 *  Copyright (c) 2017 Otávio Santana and others
 *   All rights reserved. This program and the accompanying materials
 *   are made available under the terms of the Eclipse Public License v1.0
 *   and Apache License v2.0 which accompanies this distribution.
 *   The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 *   and the Apache License v2.0 is available at http://www.opensource.org/licenses/apache2.0.php.
 *
 *   You may elect to redistribute this code under either of these licenses.
 *
 *   Contributors:
 *
 *   Otavio Santana
 */
package org.jnosql.diana.elasticsearch.document;

import org.awaitility.Awaitility;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.jnosql.diana.api.document.Document;
import org.jnosql.diana.api.document.DocumentCollectionManager;
import org.jnosql.diana.api.document.DocumentCollectionManagerAsync;
import org.jnosql.diana.api.document.DocumentDeleteQuery;
import org.jnosql.diana.api.document.DocumentEntity;
import org.jnosql.diana.api.document.DocumentQuery;
import org.jnosql.diana.api.document.Documents;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.jnosql.diana.api.document.query.DocumentQueryBuilder.delete;
import static org.jnosql.diana.api.document.query.DocumentQueryBuilder.select;
import static org.jnosql.diana.elasticsearch.document.DocumentEntityGerator.COLLECTION_NAME;
import static org.jnosql.diana.elasticsearch.document.DocumentEntityGerator.INDEX;
import static org.jnosql.diana.elasticsearch.document.DocumentEntityGerator.getEntity;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;


public class ElasticsearchDocumentCollectionManagerAsyncTest {


    private ElasticsearchDocumentCollectionManagerAsync entityManagerAsync;

    private DocumentCollectionManager entityManager;

    @BeforeEach
    public void setUp() {
        ElasticsearchDocumentConfiguration configuration = new ElasticsearchDocumentConfiguration();
        ElasticsearchDocumentCollectionManagerFactory managerFactory = configuration.get();
        entityManagerAsync = managerFactory.getAsync(COLLECTION_NAME);
        entityManager = managerFactory.get(INDEX);
        DocumentEntity documentEntity = getEntity();
        Document id = documentEntity.find("name").get();
        DocumentQuery query = select().from(COLLECTION_NAME).where(id.getName()).eq(id.get()).build();
        DocumentDeleteQuery deleteQuery = delete().from(COLLECTION_NAME).where(id.getName()).eq(id.get()).build();
        entityManagerAsync.delete(deleteQuery);
    }

    @Test
    public void shouldClose() {
        entityManager.close();
    }


    @Test
    public void shouldInsertAsync() throws InterruptedException {
        DocumentEntity entity = getEntity();
        entityManagerAsync.insert(entity);

        Thread.sleep(1_000L);
        Document id = entity.find("name").get();

        DocumentQuery query = select().from(COLLECTION_NAME).where(id.getName()).eq(id.get()).build();
        List<DocumentEntity> entities = entityManager.select(query);
        assertFalse(entities.isEmpty());

    }

    @Test
    public void shouldUpdateAsync() {
        DocumentEntity entity = getEntity();
        DocumentEntity documentEntity = entityManager.insert(entity);
        Document newField = Documents.of("newField", "10");
        entity.add(newField);
        entityManagerAsync.update(entity);
    }

    @Test
    public void shouldRemoveEntityAsync() throws InterruptedException {
        DocumentEntity documentEntity = entityManager.insert(getEntity());
        Document id = documentEntity.find("name").get();
        DocumentQuery query = select().from(COLLECTION_NAME).where(id.getName()).eq(id.get()).build();
        DocumentDeleteQuery deleteQuery = delete().from(COLLECTION_NAME).where(id.getName()).eq(id.get()).build();
        entityManagerAsync.delete(deleteQuery);

        Thread.sleep(1_000L);
        assertTrue(entityManager.select(query).isEmpty());

    }

    @Test
    public void shouldUserSearchBuilder() {
        DocumentEntity entity = getEntity();
        entityManager.insert(entity);
        TermQueryBuilder query = termQuery("name", "Poliana");
        AtomicReference<List<DocumentEntity>> result = new AtomicReference<>();

        entityManagerAsync.search(query, result::set, "person");
        Awaitility.await().until(() -> result == null);
        List<DocumentEntity> account = result.get();
        assertFalse(account.isEmpty());
    }

}
@@ -828,77 +828,8 @@
 er;%0A
-import org.jnosql.diana.api.document.DocumentCollectionManagerAsync;%0A
 impo
@@ -1135,16 +1135,66 @@
 l.List;%0A
+import java.util.concurrent.atomic.AtomicBoolean;%0A
 import j
@@ -4497,61 +4497,194 @@
 ();%0A
-%0A        entityManagerAsync.search(query, result::set
+        AtomicBoolean atomicBoolean = new AtomicBoolean(false);%0A%0A        entityManagerAsync.search(query, l -%3E %7B%0A            result.set(l);%0A            atomicBoolean.set(true);%0A        %7D
 , %22p
@@ -4688,24 +4688,25 @@
  %22person%22);%0A
+%0A
         Awai
@@ -4729,29 +4729,26 @@
 ntil
-(() -%3E result == null
+True(atomicBoolean
 );%0A 

fixes the boolean