package com.microservices.mon.k8s.controller;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.utils.PageUtils;
import com.microservices.common.core.web.controller.BaseController;
import com.microservices.common.core.web.domain.AjaxResult;
import com.microservices.common.core.web.domain.GenericsAjaxResult;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.mon.k8s.domain.*;
import com.microservices.mon.k8s.domain.vo.ApplicationEnvTypeVo;
import com.microservices.mon.k8s.domain.vo.ApplicationTypeVo;
import com.microservices.mon.k8s.domain.vo.CommonTypeVo;
import com.microservices.mon.k8s.service.IMicroManagementService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("micro")
@Api(tags = "微服务管理")
@RefreshScope
public class MicroManagementController extends BaseController {
    @Autowired
    private IMicroManagementService microManagementService;

    @ApiOperation(value = "获取可视化面板容器列表")
    @GetMapping("/pod/list")
    public GenericsTableDataInfo<K8sApplicationPod> podList() {
        return new GenericsTableDataInfo<>(microManagementService.getPodList());
    }

    @ApiOperation(value = "获取微服务运行状态监控数据")
    @GetMapping("/pod/status/{podName}")
    public GenericsAjaxResult<K8sPodContainerMetricOverview> podStatus(@PathVariable("podName") String podName,
                                                                       @RequestParam(value = "step", required = false) @ApiParam(value = "统计频率") Long step) {
        return GenericsAjaxResult.success(microManagementService.getPodStatus(podName, step));
    }

    @ApiOperation(value = "获取微服务应用详情")
    @GetMapping("/application/{kind}/{namespace}/{applicationName}/detail")
    public GenericsAjaxResult<K8sApplication> applicationDetail(@PathVariable("kind") String kind,
                                                                @PathVariable("namespace") String namespace,
                                                                @PathVariable("applicationName") String applicationName) {
        return GenericsAjaxResult.success(microManagementService.getApplicationDetail(kind, namespace, applicationName));
    }

    @ApiOperation(value = "删除POD容器")
    @DeleteMapping("/pod/{namespace}/{podName}")
    public AjaxResult applicationDetail(@PathVariable("namespace") String namespace,
                                        @PathVariable("podName") String podName,
                                        @RequestParam(value = "isForce", required = false) @ApiParam(value = "是否强制删除") Boolean isForce) {
        return toAjax(microManagementService.deletePod(namespace, podName, isForce));
    }

    @ApiOperation(value = "操作应用")
    @PutMapping("/application/{kind}/{namespace}/{applicationName}/operate/{operationKey}")
    public AjaxResult operateApplication(@PathVariable("kind") String kind,
                                         @PathVariable("namespace") String namespace,
                                         @PathVariable("applicationName") String applicationName,
                                         @PathVariable("operationKey") String operationKey) {
        return toAjax(microManagementService.operateApplication(kind, namespace, applicationName, operationKey));
    }

    @ApiOperation(value = "获取应用类型")
    @GetMapping("/applicationType")
    public GenericsTableDataInfo<ApplicationTypeVo> applicationType() {
        return new GenericsTableDataInfo<>(microManagementService.getApplicationTypeList());
    }

    @ApiOperation(value = "创建应用")
    @PostMapping("/application/{kind}")
    public AjaxResult createApplication(@PathVariable("kind") String kind,
                                        @RequestBody String yamlContent) {
        return AjaxResult.success(microManagementService.createApplication(kind, yamlContent));
    }

    @ApiOperation(value = "获取应用Yaml文件")
    @GetMapping(value = "/application/{kind}/{namespace}/{applicationName}/yamlFile", produces = "application/yaml")
    public JSONObject getApplicationYamlFile(@PathVariable("kind") String kind,
                                             @PathVariable("namespace") String namespace,
                                             @PathVariable("applicationName") String applicationName) {
        return microManagementService.getApplicationYamlFile(kind, namespace, applicationName);
    }

    @ApiOperation(value = "编辑应用Yaml文件")
    @PutMapping("/application/{kind}/{namespace}/{applicationName}")
    public AjaxResult editApplication(@PathVariable("kind") String kind,
                                      @PathVariable("namespace") String namespace,
                                      @PathVariable("applicationName") String applicationName,
                                      @RequestBody String yamlContent) {
        return toAjax(microManagementService.editApplication(kind, namespace, applicationName, yamlContent));
    }

    @ApiOperation(value = "删除应用")
    @DeleteMapping("/application/{kind}/{namespace}/{applicationName}")
    public AjaxResult deleteApplication(@PathVariable("kind") String kind,
                                        @PathVariable("namespace") String namespace,
                                        @PathVariable("applicationName") String applicationName) {
        return toAjax(microManagementService.deleteApplication(kind, namespace, applicationName));
    }

    @ApiOperation(value = "获取应用环境变量")
    @GetMapping(value = "/application/{kind}/{namespace}/{applicationName}/env")
    public GenericsTableDataInfo<K8sApplicationEnv> getApplicationEnv(@PathVariable("kind") String kind,
                                                                      @PathVariable("namespace") String namespace,
                                                                      @PathVariable("applicationName") String applicationName) {
        return new GenericsTableDataInfo<>(microManagementService.getApplicationEnv(kind, namespace, applicationName));
    }

    @ApiOperation(value = "获取应用环境变量相关可选参数")
    @GetMapping(value = "/application/{namespace}/envOptionalParameters")
    public GenericsTableDataInfo<K8sApplicationEnvOptionalParameter> getEnvOptionalParameters(@PathVariable("namespace") String namespace) {
        return new GenericsTableDataInfo<>(microManagementService.getEnvOptionalParameters(namespace));
    }

    @ApiOperation(value = "更新应用环境变量")
    @PutMapping("/application/{kind}/{namespace}/{applicationName}/env")
    public AjaxResult updateApplicationEnv(@PathVariable("kind") String kind,
                                           @PathVariable("namespace") String namespace,
                                           @PathVariable("applicationName") String applicationName,
                                           @RequestBody List<K8sApplicationEnv> k8sApplicationEnvList) {
        return toAjax(microManagementService.updateApplicationEnv(kind, namespace, applicationName, k8sApplicationEnvList));
    }

    @ApiOperation(value = "获取应用环境变量类型")
    @GetMapping(value = "/application/envTypes")
    public GenericsTableDataInfo<ApplicationEnvTypeVo> getEnvTypes() {
        return new GenericsTableDataInfo<>(microManagementService.getEnvTypes());
    }

    @ApiOperation(value = "获取网关路由配置")
    @GetMapping(value = "/gateway/routeConfig")
    public GenericsTableDataInfo<GatewayRouteConfig> getGatewayRouteConfig() {
        return new GenericsTableDataInfo<>(microManagementService.getGatewayRouteConfig());
    }

    @ApiOperation(value = "更新网关路由配置")
    @PutMapping(value = "/gateway/routeConfig")
    public AjaxResult updateGatewayRouteConfig(@RequestBody List<GatewayRouteConfig> gatewayRouteConfigList) {
        return toAjax(microManagementService.updateGatewayRouteConfig(gatewayRouteConfigList));
    }

    @ApiOperation(value = "获取网关安全认证配置")
    @GetMapping(value = "/gateway/safetyConfig")
    public GenericsAjaxResult<GatewaySafetyConfig> getGatewaySafetyConfig() {
        return GenericsAjaxResult.success(microManagementService.getGatewaySafetyConfig());
    }

    @ApiOperation(value = "更新网关安全认证配置")
    @PutMapping(value = "/gateway/safetyConfig")
    public AjaxResult updateGatewaySafetyConfig(@RequestBody GatewaySafetyConfig gatewaySafetyConfig) {
        return toAjax(microManagementService.updateGatewaySafetyConfig(gatewaySafetyConfig));
    }

    @ApiOperation(value = "获取网关白名单配置")
    @GetMapping(value = "/gateway/whitelistConfig")
    public GenericsAjaxResult<GatewayWhitelistConfig> getGatewayWhitelistConfig() {
        return GenericsAjaxResult.success(microManagementService.getGatewayWhitelistConfig());
    }

    @ApiOperation(value = "更新网关白名单配置")
    @PutMapping(value = "/gateway/whitelistConfig")
    public AjaxResult updateGatewayWhitelistConfig(@RequestBody GatewayWhitelistConfig gatewayWhitelistConfig) {
        return toAjax(microManagementService.updateGatewayWhitelistConfig(gatewayWhitelistConfig));
    }

    @ApiOperation(value = "获取存在网关异常处理记录的日期列表")
    @GetMapping(value = "/gateway/exceptionHandingDateList")
    public GenericsTableDataInfo<String> getExceptionHandingDateList() {
        return new GenericsTableDataInfo<>(microManagementService.getExceptionHandingDateList());
    }

    @ApiOperation(value = "获取网关异常处理记录")
    @GetMapping(value = "/gateway/exceptionHandingRecordList")
    public GenericsTableDataInfo<String> getExceptionHandingRecordList(@RequestParam(value = "date", required = false) @ApiParam(value = "查看日期") String date) {
        return new GenericsTableDataInfo<>(microManagementService.getExceptionHandingRecordList(date));
    }

    @ApiOperation(value = "获取网关限流跳转参数")
    @GetMapping(value = "/gateway/flowLimitingPara")
    public GenericsAjaxResult<JSONObject> getGatewayFlowLimitingPara() {
        return GenericsAjaxResult.success(microManagementService.getGatewayFlowLimitingPara());
    }

    @ApiOperation(value = "获取链路追踪应用列表")
    @GetMapping(value = "/application/linkTrackingList")
    public GenericsTableDataInfo<LinkTrackingApplication> getLinkTrackingList(@RequestParam(value = "applicationName", required = false) @ApiParam(value = "应用名称") String applicationName) {
        return new GenericsTableDataInfo<>(microManagementService.getLinkTrackingList(applicationName));
    }

    @ApiOperation(value = "获取K8S事件关键活动操作列表")
    @GetMapping(value = "/k8sEvent/keyActivitiesOperationList")
    public GenericsTableDataInfo<CommonTypeVo> getKeyActivitiesOperationList() {
        return new GenericsTableDataInfo<>(microManagementService.getK8SEventReasonList("Normal"));
    }

    @ApiOperation(value = "获取K8S事件关键活动列表")
    @GetMapping(value = "/k8sEvent/keyActivitiesList")
    public GenericsTableDataInfo<K8SEvent> getKeyActivitiesList(@RequestParam(value = "reason", required = false) @ApiParam(value = "操作类型") String reason,
                                                                @RequestParam(value = "startTime", required = false) @ApiParam(value = "开始时间") Date startTime,
                                                                @RequestParam(value = "endTime", required = false) @ApiParam(value = "结束时间") Date endTime,
                                                                @RequestParam(value = "isAscOrderByOccurredTime", required = false) @ApiParam(value = "是否根据发生时间升序排序（默认根据发生时间降序排序）") Boolean isAscOrderByOccurredTime,
                                                                @RequestParam(value = "pageNum", required = false) @ApiParam(value = "当前记录起始索引") Integer pageNum,
                                                                @RequestParam(value = "pageSize", required = false) @ApiParam(value = "每页显示记录数") Integer pageSize) {
        return microManagementService.getK8SEventList("Normal", reason, startTime, endTime, isAscOrderByOccurredTime, pageNum, pageSize);
    }

    @ApiOperation(value = "获取K8S事异常结束事件原因列表")
    @GetMapping(value = "/k8sEvent/exceptionEndReasonList")
    public GenericsTableDataInfo<CommonTypeVo> getExceptionEndReasonList() {
        return new GenericsTableDataInfo<>(microManagementService.getK8SEventReasonList("Warning"));
    }

    @ApiOperation(value = "获取K8S事件异常结束事件列表")
    @GetMapping(value = "/k8sEvent/exceptionEndList")
    public GenericsTableDataInfo<K8SEvent> getExceptionEndListList(@RequestParam(value = "reason", required = false) @ApiParam(value = "操作类型") String reason,
                                                                   @RequestParam(value = "startTime", required = false) @ApiParam(value = "开始时间") Date startTime,
                                                                   @RequestParam(value = "endTime", required = false) @ApiParam(value = "结束时间") Date endTime,
                                                                   @RequestParam(value = "isAscOrderByOccurredTime", required = false) @ApiParam(value = "是否根据发生时间升序排序（默认根据发生时间降序排序）") Boolean isAscOrderByOccurredTime,
                                                                   @RequestParam(value = "pageNum", required = false) @ApiParam(value = "当前记录起始索引") Integer pageNum,
                                                                   @RequestParam(value = "pageSize", required = false) @ApiParam(value = "每页显示记录数") Integer pageSize) {
        return microManagementService.getK8SEventList("Warning", reason, startTime, endTime, isAscOrderByOccurredTime, pageNum, pageSize);
    }


    @ApiOperation(value = "获取K8S资源对象列表")
    @GetMapping(value = "/k8sEvent/resourceObjectList")
    public GenericsTableDataInfo<CommonTypeVo> getResourceObjectList() {
        return new GenericsTableDataInfo<>(microManagementService.getResourceObjectList());
    }

    @ApiOperation(value = "获取K8S资源占用列表")
    @GetMapping(value = "/k8sEvent/resourceUsageList")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "当前记录起始索引", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页显示记录数", paramType = "query", dataType = "Integer")
    })
    public GenericsTableDataInfo<K8SResourceUsage> getResourceUsageList(@RequestParam(value = "searchResourceObject", required = false) @ApiParam(value = "资源对象") String searchResourceObject,
                                                                        @RequestParam(value = "startTime", required = false) @ApiParam(value = "开始时间") Date startTime,
                                                                        @RequestParam(value = "endTime", required = false) @ApiParam(value = "结束时间") Date endTime) {
        return getAllGenericsDataTableToPage(microManagementService.getResourceUsageList(searchResourceObject, startTime, endTime));
    }
}
