package com.artfess.es.unit;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public interface ElasticSearchApplication {

    /**
     * 判断某条数据是否存在
     * @param indexName 索引名
     * @param id id
     * @return boolean
     */
    boolean existsIndex(String indexName, String id);

    /**
     * 单条新增数据
     * @param indexName 索引库
     * @param id 可有可无，当有的时候，如果数据库中有对应id的数据就执行修改，否则就增加；无id时，将系统生产
     * @param t 数据(json格式的T对象)
     * @return 是否成功
     */
    <T>  boolean insertDocument(String indexName, String id, T t);

    /**
     * 批量新增数据
     * @param indexName 索引库
     * @param list list集合 集合中的数据必须支持转json格式)
     * @return 是否成功
     */
    <T>  boolean insertDocument(String indexName, List<T> list) throws IOException;

    /**
     * 批量新增数据
     * @param indexName 索引库
     * @param pipeLine 管道名称
     * @param list list集合 集合中的数据必须支持转json格式)
     * @return 是否成功
     */
    <T>  boolean insertDocument(String indexName, String pipeLine,List<T> list) throws IOException;

    /**
     * 修改指定索引库中的某一数据
     * @param indexName 索引库
     * @param id id
     * @param map 数据对象
     */
    void updateById(String indexName, String id, Map<String, Object> map);

    /**
     * 修改指定索引库中的某一数据
     * @param indexName 索引库
     * @param ids id集合
     * @param map 数据对象
     */
    void updateById(String indexName, List<String> ids, Map<String, Object> map);

    /**
     * 对符合条件的数据进行特定的数据修改————少字段的更新，不适合全文性的内容更新，最大长度：65535
     * @param indexName 索引库
     * @param queryBuilder 查询条件构造
     * @param map 修改的数据值
     * @return 行数
     */
    Long updateByQueryBuilder(String indexName, QueryBuilder queryBuilder, Map<String, Object> map);

    /**
     * 异步对符合条件的数据进行特定的数据修改
     * @param indexName 索引库
     * @param queryBuilder 查询条件构造
     * @param map 修改的数据值
     * @return 行数
     */
    void updateByQueryBuilderOfAsync(String indexName, QueryBuilder queryBuilder, Map<String, Object> map, ActionListener<BulkByScrollResponse> actionListener);

    /**
     * 通过Id删除指定索引库中的某一数据
     * @param indexName 索引库
     * @param id id
     */
    void delById(String indexName, String id);


    /**
     * 通过id批量删除指定索引库中的数据
     * @param indexName 索引库
     * @param ids id集合
     */
    void delByIds(String indexName, List<String> ids);

    /**
     * 通过查询条件进行数据删除
     * @param indexName 索引库
     * @param queryBuilder 查询条件封装
     * @return 受影响的数量
     */
    Long delByQuery(String indexName, QueryBuilder queryBuilder);

    /**
     * 通过id查询指定索引库中的指定数据
     * @param indexName 索引库
     * @param id 数据id
     * @return 返回对象不包括Map与GetResponse
     */
    <T> T queryById(String indexName, String id, Class<T> c);

    /**
     * 通过id查询指定索引库中的指定数据
     * @param indexName 索引库
     * @param id 数据id
     * @return GetResponse
     */
    GetResponse queryGetResponseById(String indexName, String id);
    /**
     * 通过id查询指定索引库中的指定数据
     * @param indexName 索引库
     * @param id 数据id
     * @return map集合
     */
    Map<String, Object> queryMapById(String indexName, String id);

    /**
     * 查询指定索引库中符合条件的数据
     * @param indexName 索引库
     * @param queryBuilder 数据查询条件构造
     * @return map集合
     */
    List<Map<String, Object>> queryDataByQueryBuilder(String indexName, QueryBuilder queryBuilder);

    /**
     * 查询指定索引库中符合条件的数据
     * @param indexName 索引名称
     * @param queryBuilder 数据查询条件构造
     * @return
     */
    List<Map<String, Object>> queryDataByQueryBuilder(String indexName, BoolQueryBuilder queryBuilder,SortOrder sortOrder,List<String> filedName);

    /**
     * 全文检索
     * @param indexName 索引库
     * @param searchSourceBuilder 查询条件封装
     * @param pageNum 起始页
     * @param pageSize 页大小
     * @param fieldNameForSort 排序字段
     * @param sortOrder 排序规则
     * @param heightFields 高亮字段
     * @return map——键值对，data表示返回的数据，total表示符合条件的数据总条数
     */
    Map<String, Object> queryForFullText(String indexName, SearchSourceBuilder searchSourceBuilder,
                                         int pageNum, int pageSize, List<String> fieldNameForSort,
                                         SortOrder sortOrder, String[] heightFields);

    /**
     * 查询指定索引库中符合条件的数据
     * @param indexName 索引名称
     * @param queryBuilder 数据查询条件构造
     * @param pageNum
     * @param pageSize
     * @return
     */
    Map<String, Object> queryDataByQueryBuilder(String indexName,QueryBuilder queryBuilder, Integer pageNum, Integer pageSize);

    /**
     * 查询指定索引库中符合条件的数据
     * @param indexName 索引名称
     * @param queryBuilder 数据查询条件构造
     * @param pageNum
     * @param pageSize
     * @param order 排序
     * @return
     */
    Map<String, Object> queryDataByQueryBuilder(String indexName, QueryBuilder queryBuilder,String name, SortOrder order, Integer pageNum, Integer pageSize);



    /**
     * 聚合统计
     * @param indexName 索引名称
     * @param queryBuilder 查询条件
     * @param aggregationBuilder 聚合
     * @return Aggregations
     * @throws IOException
     */
    SearchResponse queryForAggregation(String indexName, QueryBuilder queryBuilder, AggregationBuilder aggregationBuilder) throws IOException;

    /**
     * 通过查询条件进行数据量统计
     * @param indexName
     * @param queryBuilder
     */
    Long countByQueryBuilder(String indexName, QueryBuilder queryBuilder);

    /**
     * 推荐候选词搜索
     * @param idxName
     * @param builder
     * @return
     */
    List<String> searchCompletionSuggest(String idxName, SearchSourceBuilder builder);
}
