package com.lanyuanxiaoyao.service.web.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lanyuanxiaoyao.service.common.entity.RunMeta;
import com.lanyuanxiaoyao.service.common.utils.NameHelper;
import com.lanyuanxiaoyao.service.configuration.ExecutorProvider;
import com.lanyuanxiaoyao.service.configuration.entity.zookeeper.ZookeeperNode;
import com.lanyuanxiaoyao.service.forest.service.ZookeeperService;
import com.lanyuanxiaoyao.service.web.controller.base.AmisCrudResponse;
import com.lanyuanxiaoyao.service.web.controller.base.AmisResponse;
import com.lanyuanxiaoyao.service.web.controller.base.BaseController;
import com.lanyuanxiaoyao.service.web.entity.ZookeeperNodeVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 运行时监控
 *
 * @author lanyuanxiaoyao
 * @date 2023-05-23
 */
@RestController
@RequestMapping("running")
public class RunningController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(RunningController.class);

    private final ZookeeperService zookeeperService;
    private final ObjectMapper mapper;

    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    public RunningController(ZookeeperService zookeeperService, Jackson2ObjectMapperBuilder builder) {
        this.zookeeperService = zookeeperService;
        this.mapper = builder.build();
    }

    @GetMapping("sync")
    public AmisCrudResponse sync() {
        return AmisResponse.responseCrudData(
                zookeeperService.getChildren(NameHelper.ZK_SYNC_RUNNING_LOCK_PATH)
                        .asParallel(ExecutorProvider.EXECUTORS, 1)
                        .collect(this::parseRunMeta)
                        .toSortedListBy(ZookeeperNodeVO::getCreateTime)
                        .toReversed()
                        .toImmutable()
        );
    }

    @GetMapping("compaction")
    public AmisCrudResponse compaction() {
        return AmisResponse.responseCrudData(
                zookeeperService.getChildren(NameHelper.ZK_COMPACTION_RUNNING_LOCK_PATH)
                        .asParallel(ExecutorProvider.EXECUTORS, 1)
                        .collect(this::parseRunMeta)
                        .toSortedListBy(ZookeeperNodeVO::getCreateTime)
                        .toReversed()
                        .toImmutable()
        );
    }

    private ZookeeperNodeVO parseRunMeta(ZookeeperNode node) {
        RunMeta meta = null;
        try {
            String data = zookeeperService.getData(node.getPath());
            meta = mapper.readValue(data, RunMeta.class);
        } catch (JsonProcessingException e) {
            logger.warn("Json parse failure for" + node.getPath(), e);
        }
        return new ZookeeperNodeVO(node, meta);
    }
}
