package com.search.supersearch;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
import co.elastic.clients.elasticsearch.indices.GetIndexResponse;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

import java.io.IOException;
import java.util.Map;

/**
 * 测试 elasticSearch client 索引相关的操作
 *
 * @author WT
 * @date 2021/12/28 16:27:45
 */
@Slf4j
@SpringBootTest
@ActiveProfiles("wr") //这里
public class ElasticsearchClientIndexTest {

    @Autowired
    private ElasticsearchClient elasticsearchClient;

    // 创建索引 - 不指定 mapping
    @Test
    public void run() throws IOException {
        String sql = "INSERT INTO `xcapp`.`iam_search_categoryid_indexname` (`category_id`, `category_name`, `index_name`, `index_remark`, `query_fields`, `sort_fields`, `highlight_fields`, `system_id`, `system_name`, `index_source`, `type`, `CREATOR_ID`, `CREATOR_ACCOUNT`, `CREATOR_NAME`, `CREATE_DEPT_ID`, `CREATE_DEPT_CODE`, `CREATE_DEPT_NAME`, `MODIFY_EMP_ID`, `MODIFY_EMP_ACCOUNT`, `MODIFY_EMP_NAME`, `MODIFY_DEPT_ID`, `MODIFY_DEPT_CODE`, `MODIFY_DEPT_NAME`, `CREATION_TIME`, `LAST_MODIFIED_TIME`, `DELETED`, `BELONGED_ORG_ID`) VALUES (NULL, NULL, '%s', '%s', NULL, NULL, NULL, '002002', '002002', NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, -1);";
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            CreateIndexResponse createIndexResponse = elasticsearchClient.indices()
                    .create(createIndexRequest ->
                            createIndexRequest.index("xiayuan_" + finalI)
                    );
//            log.info("== {} 索引创建是否成功: {}", "elasticsearch-client", createIndexResponse.acknowledged());
            log.info(String.format(sql, finalI, finalI));
        }
    }

    @Test
    public void run2() throws IOException {
        String sql = "INSERT INTO `iam_search_categoryid_indexname` (`category_id`, `category_name`, `index_name`, `index_remark`, `query_fields`, `sort_fields`, `highlight_fields`, `system_id`, `system_name`, `index_source`, `type`, `CREATOR_ID`, `CREATOR_ACCOUNT`, `CREATOR_NAME`, `CREATE_DEPT_ID`, `CREATE_DEPT_CODE`, `CREATE_DEPT_NAME`, `MODIFY_EMP_ID`, `MODIFY_EMP_ACCOUNT`, `MODIFY_EMP_NAME`, `MODIFY_DEPT_ID`, `MODIFY_DEPT_CODE`, `MODIFY_DEPT_NAME`, `CREATION_TIME`, `LAST_MODIFIED_TIME`, `DELETED`, `BELONGED_ORG_ID`) VALUES (NULL, NULL, '%s', '%s', NULL, NULL, NULL, '002002', '002002', NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, -1);";
        for (int i = 0; i < 20; i++) {
            System.out.printf((sql) + "%n", "xiayuan_" + i, "xiayuan_" + i);
        }
    }

    // 创建索引 - 不指定 mapping
    @Test
    public void createIndex() throws IOException {
        CreateIndexResponse createIndexResponse = elasticsearchClient.indices()
                .create(createIndexRequest ->
                        createIndexRequest.index("fenpian-0").settings(s->s.numberOfReplicas("0").numberOfShards("1"))
                );
        log.info("== {} 索引创建是否成功: {}", "elasticsearch-client", createIndexResponse.acknowledged());
    }

    // 创建索引 - 指定 mapping
    @Test
    public void createIndexWithMapping() throws IOException {

        CreateIndexResponse createIndexResponse = elasticsearchClient.indices()
                .create(createIndexRequest ->
                        createIndexRequest.index("elasticsearch-client")
                                // 用 lambda 的方式 下面的 mapping 会覆盖上面的 mapping
                                .mappings(
                                        typeMapping ->
                                                typeMapping.properties("name", objectBuilder ->
                                                        objectBuilder.text(textProperty -> textProperty.fielddata(true).analyzer("ik_smart"))
                                                ).properties("age", objectBuilder ->
                                                        objectBuilder.integer(integerNumberProperty -> integerNumberProperty.index(true))
                                                )
                                )
                );

        log.info("== {} 索引创建是否成功: {}", "elasticsearch-client", createIndexResponse.acknowledged());
    }

    // 判断索引是否存在
    @Test
    public void indexIsExist() throws IOException {
        BooleanResponse booleanResponse = elasticsearchClient.indices()
                .exists(existsRequest ->
                        existsRequest.index("elasticsearch-client")
                );

        log.info("== {} 索引创建是否存在: {}", "elasticsearch-client", booleanResponse.value());
    }

    // 查看索引的相关信息
    @Test
    public void indexDetail() throws IOException {
        GetIndexResponse getIndexResponse = elasticsearchClient.indices()
                .get(getIndexRequest ->
                        getIndexRequest.index("elasticsearch-client")
                );

        Map<String, Property> properties = getIndexResponse.get("elasticsearch-client").mappings().properties();

        for (String key : properties.keySet()) {
            log.info("== {} 索引的详细信息为: == key: {}, Property: {}", "elasticsearch-client", key, properties.get(key)._kind());
        }

    }

    // 删除索引
    @Test
    public void deleteIndex() throws IOException {
        DeleteIndexResponse deleteIndexResponse = elasticsearchClient.indices()
                .delete(deleteIndexRequest ->
                        deleteIndexRequest.index("elasticsearch-client")
                );

        log.info("== {} 索引创建是否删除成功: {}", "elasticsearch-client", deleteIndexResponse.acknowledged());
    }

    @Test
    public void testRestClient() throws IOException {
        SearchResponse<Map> search = elasticsearchClient.search(s -> s.index("test_docs1")
                        .query(q -> q.match(t -> t
                                .field("content")
                                .query("电力")
                        ))
                        .highlight(h -> h.fields("content", hf -> hf))


                ,
                Map.class);

        for (Hit<Map> hit : search.hits().hits()) {
            log.info("== hit: {}", hit.source());
//            System.out.println("== hit: hit.source()" );
        }

    }

}
