/* (C) 2024 YiRing, Inc. */
package com.yiring.app.web.common;

import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson2.JSONObject;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.yiring.auth.domain.user.UserRepository;
import com.yiring.common.core.Minio;
import com.yiring.common.core.Redis;
import com.yiring.common.core.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author Jim
 */
@Slf4j
@Validated
@ApiSupport(order = -99999)
@Tag(name = "Health", description = "Health")
@RequestMapping("/health")
@RestController
@RequiredArgsConstructor
public class HealthController {

    final Redis redis;
    final Minio minio;
    final UserRepository userRepository;

    @SaIgnore
    @Operation(summary = "健康检查")
    @GetMapping
    public Result<JSONObject> health(HttpServletResponse response) {
        JSONObject data = new JSONObject();
        boolean health = true;

        // Redis
        try {
            redis.info();
            data.put("redis", "up");
        } catch (Exception e) {
            log.error("[Health] redis usability fail: {}", e.getMessage());
            data.put("redis", "down: " + e.getMessage());
            health = false;
        }

        // Database
        try {
            userRepository.count();
            data.put("database", "up");
        } catch (Exception e) {
            log.error("[Health] database usability fail: {}", e.getMessage());
            data.put("database", "down: " + e.getMessage());
            health = false;
        }

        // MinIO
        try {
            boolean result = minio.isValid();
            data.put("minio", result ? "up" : "down");
        } catch (Exception e) {
            log.error("[Health] minio usability fail: {}", e.getMessage());
            data.put("minio", "down: " + e.getMessage());
            health = false;
        }

        // RabbitMQ
        //        try {
        //            rabbitTemplate.send(new Message("health".getBytes()));
        //            data.put("rabbitmq", "up");
        //        } catch (Exception e) {
        //            log.error("[Health] rabbitmq usability fail: {}", e.getMessage());
        //            data.put("rabbitmq", "down: " + e.getMessage());
        //            health = false;
        //        }

        if (!health) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }

        return Result.ok(data);
    }
}
