package com.microservices.mon.k8s.utils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;

import java.util.Date;

/**
 * Prometheus查询常量
 */
public class ESQueryUtils {
    public static JSONObject buildEventListQueryBody(String eventType, String reason, Date startTime, Date endTime, Boolean isAscOrderByOccurredTime, Integer pageNum, Integer pageSize) {
        // 根对象
        JSONObject root = new JSONObject();

        if (pageSize == null || pageSize <= 0) {
            pageSize = 20;
        }
        /* 1. size */
        root.put("size", pageSize);
        if (pageNum != null && pageNum > 0) {
            root.put("from", (pageNum - 1) * pageSize);
        }

        /* 2. query -> bool -> must 数组 */
        JSONArray must = new JSONArray();

        // term: type = Normal
        must.add(
                new JSONObject().fluentPut(
                        "term",
                        new JSONObject().fluentPut("type.keyword", eventType)
                )
        );
        if (StringUtils.isNotEmpty(reason)) {
            // term: reason.keyword = Killing
            must.add(
                    new JSONObject().fluentPut(
                            "term",
                            new JSONObject().fluentPut("reason.keyword", reason)
                    )
            );
        }

        if (startTime != null || endTime != null) {
            if (startTime != null && endTime != null && startTime.after(endTime)) {
                throw new ServiceException("开始时间不能晚于结束时间");
            }
            JSONObject timeRange = new JSONObject();
            if (startTime != null) {
                timeRange.put("gte", startTime);
            }
            if (endTime != null) {
                timeRange.put("lte", endTime);
            }
            // range: lastTimestamp
            JSONObject range = new JSONObject()
                    .fluentPut("lastTimestamp", timeRange);
            must.add(new JSONObject().fluentPut("range", range));
        }


        // 组装 bool
        JSONObject bool = new JSONObject().fluentPut("must", must);
        root.put("query", new JSONObject().fluentPut("bool", bool));
        String order = "desc";
        if (isAscOrderByOccurredTime != null && isAscOrderByOccurredTime) {
            order = "asc";
        }
        /* 3. sort 数组 */
        JSONArray sort = new JSONArray();
        sort.add(
                new JSONObject().fluentPut(
                        "lastTimestamp",
                        new JSONObject().fluentPut("order", order)
                )
        );
        root.put("sort", sort);
        return root;
    }

    public static JSONObject buildEventReasonListQueryBody(String eventType) {
        // 根对象
        JSONObject root = new JSONObject();

        /* 1. size = 0 */
        root.put("size", 0);

        /* 2. query -> bool -> must */
        JSONArray must = new JSONArray();
        must.add(
                new JSONObject().fluentPut(
                        "term",
                        new JSONObject().fluentPut("type.keyword", eventType)
                )
        );
        JSONObject bool = new JSONObject().fluentPut("must", must);
        root.put("query", new JSONObject().fluentPut("bool", bool));

        /* 3. aggs -> distinct_reasons -> terms */
        JSONObject terms = new JSONObject().fluentPut("field", "reason.keyword");
        JSONObject distinctReasons = new JSONObject().fluentPut("terms", terms);
        root.put("aggs", new JSONObject().fluentPut("distinct_reasons", distinctReasons));
        return root;
    }

    public static JSONObject buildAlarmEventListQueryBody() {
        // 根对象
        JSONObject root = new JSONObject();
        /* 2. query -> bool -> must 数组 */
        JSONArray mustNot = new JSONArray();
        mustNot.add(
                new JSONObject().fluentPut(
                        "term",
                        new JSONObject().fluentPut("reason.keyword", "Unhealthy")
                )
        );
        mustNot.add(
                new JSONObject().fluentPut(
                        "term",
                        new JSONObject().fluentPut("sendNotification", true)
                )
        );

        /* 2. query -> bool -> must 数组 */
        JSONArray must = new JSONArray();

        // term: type = Normal
        must.add(
                new JSONObject().fluentPut(
                        "term",
                        new JSONObject().fluentPut("type.keyword", "Warning")
                )
        );
        // 获取最近30秒的异常事件
        Date endTime = DateUtils.getNowDate();
        long endTimeSec = endTime.getTime() / 1000;
        // 开始时间为当前时间减去1小时
        long startTimeSec = endTimeSec - 300;
        JSONObject timeRange = new JSONObject();
        timeRange.put("gte", new Date(startTimeSec * 1000));
        timeRange.put("lte", endTime);
        // range: lastTimestamp
        JSONObject range = new JSONObject()
                .fluentPut("lastTimestamp", timeRange);
        must.add(new JSONObject().fluentPut("range", range));


        // 组装 bool
        JSONObject bool = new JSONObject().fluentPut("must", must).fluentPut("must_not", mustNot);
        root.put("query", new JSONObject().fluentPut("bool", bool));
        /* 3. sort 数组 */
        JSONArray sort = new JSONArray();
        sort.add(
                new JSONObject().fluentPut(
                        "lastTimestamp",
                        new JSONObject().fluentPut("order", "asc")
                )
        );
        root.put("sort", sort);
        return root;
    }
}
