import com.dySweetFishPlugin.elasticsearch.ESClient
import com.sdtool.common.api.ESHitInfoExecutor
import com.sdtool.common.api.QueryBuilderExecutor
import com.sweetfish.convert.json.JsonConvert
import org.elasticsearch.action.search.SearchResponse
import org.elasticsearch.index.query.QueryBuilder
import org.elasticsearch.search.SearchHit

/**
 * Created by jlutt on 2022-04-20
 *
 * @author jlutt
 */

class ESOne<T> {

    private ESClient esClient

    private JsonConvert jsonConvert

    private Class<T> clazz

    private QueryBuilderExecutor qbe

    private String index

    private ESHitInfoExecutor<T> de

    static <T> ESOne<T> getESOneInfo() {
        return new ESOne<>()
    }

    ESOne<T> esClient(ESClient value) {
        this.esClient = value
        return this
    }

    ESOne<T> jsonConvert(JsonConvert value) {
        this.jsonConvert = value
        return this
    }

    ESOne<T> clazz(Class<T> value) {
        this.clazz = value
        return this
    }

    ESOne<T> queryBuilder(QueryBuilderExecutor value) {
        this.qbe = value
        return this
    }

    ESOne<T> index(String value) {
        this.index = value
        return this
    }

    ESOne<T> hitExecutor(ESHitInfoExecutor<T> value) {
        this.de = value
        return this
    }

    T execute() {
        QueryBuilder qb = qbe.execute(null)

        SearchResponse scrollResp = esClient.getClient().prepareSearch(index)
                .setQuery(qb)
                .setSize(1)
                .execute()
                .actionGet()
        if (scrollResp.getHits().getTotalHits() == 0) {
            return null
        } else {
            SearchHit hit = scrollResp.getHits().getHits()[0]
            if (de != null) {
                return de.execute(hit)
            } else {
                return jsonConvert.convertFrom(clazz, hit.getSourceAsString())
            }
        }
    }

}
