package cn.reghao.autodop.dmaster.machine.db.query;

import cn.reghao.autodop.dmaster.machine.model.po.NodeLog;
import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @author reghao
 * @date 2021-06-17 15:12:02
 */
@Component
public class MongoQuery {
    private final MongoTemplate mongoTemplate;

    public MongoQuery(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    public List<NodeLog> aggregate(String col, Map<String, String> groupByIds) {
        Document groupBy = new Document();
        groupBy.putAll(groupByIds);

        Document groupByObject = new Document("_id", groupBy);
        groupByObject.put("machineIpv4", new BasicDBObject("$first", "$machineIpv4"));
        groupByObject.put("total", new BasicDBObject("$sum", 1));

        Document queryObject = new Document("$group", groupByObject);
        List<Document> pipeline = new ArrayList<>();
        pipeline.add(queryObject);

        List<NodeLog> list = new ArrayList<>();
        AggregateIterable<Document> result = mongoTemplate.getCollection(col).aggregate(pipeline).allowDiskUse(true);
        for (Document document : result) {
            Document doc = document.get("_id", Document.class);
            String machineId = doc.get("machineId", String.class);
            String appId = doc.get("appId", String.class);
            String machineIpv4 = document.get("machineIpv4", String.class);
            Integer total = document.get("total", Integer.class);
            list.add(new NodeLog());
        }
        return list;
    }

    public List<NodeLog> aggregate1(String col, String machineId, String appId) {
        Map<String, String> matchMap = new HashMap<>();
        matchMap.put("machineId", machineId);
        matchMap.put("appId", appId);
        Document matchObject = new Document("$match", matchMap);

        Map<String, String> groupMap = new HashMap<>();
        groupMap.put("format", "%Y-%m-%d");
        groupMap.put("date", "$createTime");
        Document groupBy = new Document("yearMonthDay",
                new BasicDBObject("$dateToString", new BasicDBObject(groupMap)));
        Document groupByObject = new Document("_id", groupBy);
        groupByObject.put("total", new BasicDBObject("$sum", 1));
        Document groupObject = new Document("$group", groupByObject);

        List<Document> pipeline = new ArrayList<>();
        pipeline.add(matchObject);
        pipeline.add(groupObject);

        List<NodeLog> list = new ArrayList<>();
        AggregateIterable<Document> result = mongoTemplate.getCollection(col).aggregate(pipeline).allowDiskUse(true);
        for (Document document : result) {
            Document doc = document.get("_id", Document.class);
            String yearMonthDay = doc.get("yearMonthDay", String.class);
            Integer total = document.get("total", Integer.class);
            list.add(new NodeLog());
        }
        return list;
    }

    public List query(String machineId, String appId, String yearMonthDay) {
        LocalDate localDate = LocalDate.parse(yearMonthDay, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate localDate1 = localDate.plusDays(1);

        Query query = new Query();
        query.addCriteria(Criteria.where("machineId").is(machineId));
        query.addCriteria(Criteria.where("appId").is(appId));
        query.addCriteria(Criteria.where("createTime").gte(localDate.atStartOfDay())
                .andOperator(Criteria.where("createTime").lt(localDate1.atStartOfDay())));
        return mongoTemplate.find(query, null);
    }
}
