package com.sf.service.gateway.controller;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;

import com.sf.service.gateway.domain.GatewayInterfaceInfo;
import com.sf.service.gateway.domain.GatewayInterfaceLinkStrategy;
import com.sf.service.gateway.domain.GatewayServer;
import com.sf.service.gateway.domain.GatewayStrategy;
import com.sf.service.gateway.domain.dto.InsertGatewayInterfaceInfoDTO;
import com.sf.service.gateway.domain.dto.UpdateDataStatusDTO;
import com.sf.service.gateway.domain.dto.UpdateGatewayInterfaceInfoDTO;
import com.sf.service.gateway.domain.vo.GatewayInterfaceInfoDetailedVO;
import com.sf.service.gateway.domain.vo.GatewayInterfaceInfoListVO;
import com.sf.service.gateway.domain.vo.GatewayStrategyListVO;
import com.sf.service.gateway.enums.GatewayDataStatus;
import com.sf.service.gateway.service.IGatewayInterfaceInfoService;
import com.sf.service.gateway.service.IGatewayServerService;
import com.sf.service.gateway.service.IGatewayStrategyService;
import com.sf.service.index.util.AppUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sf.common.annotation.Log;
import com.sf.common.core.controller.BaseController;
import com.sf.common.core.domain.AjaxResult;
import com.sf.common.enums.BusinessType;
import com.sf.common.utils.poi.ExcelUtil;
import com.sf.common.core.page.TableDataInfo;

/**
 * 接口管理Controller
 * 
 * @author zoukun
 * @date 2024-04-22
 */
@Api("网关服务-接口管理")
@RestController
@RequestMapping("/gateway/interface")
public class GatewayInterfaceInfoController extends BaseController
{
    @Autowired
    private IGatewayInterfaceInfoService gatewayInterfaceInfoService;

    @Autowired
    private IGatewayServerService gatewayServerService;

    @Autowired
    private IGatewayStrategyService gatewayStrategyService;

    @ApiOperation("查询接口信息列表")
    @PreAuthorize("@ss.hasPermi('gateway:interface:list')")
    @GetMapping("/list")
    public TableDataInfo list(GatewayInterfaceInfo gatewayInterfaceInfo)
    {
        gatewayInterfaceInfo.setAppCode(AppUtils.getAppCodeFromRequestHeader());
        startPage();
        List<GatewayInterfaceInfo> list = gatewayInterfaceInfoService.selectGatewayInterfaceInfoList(gatewayInterfaceInfo);
        Set<Long> serverIds = list.stream().map(GatewayInterfaceInfo::getServerId).collect(Collectors.toSet());
        List<GatewayServer> serverList = gatewayServerService.selectGatewayServerByIds(serverIds);
        Map<Long, String> serverIdAndNameMap = serverList.stream().collect(Collectors.toMap(GatewayServer::getId, GatewayServer::getServerName));
        List<GatewayInterfaceInfoListVO> voList = list.stream().map(info -> {
            GatewayInterfaceInfoListVO vo = new GatewayInterfaceInfoListVO();
            vo.setId(info.getId());
            vo.setInterfaceName(info.getInterfaceName());
            vo.setInterfacePath(info.getInterfacePath());
            vo.setRequestMethod(info.getRequestMethod());
            vo.setDescription(info.getDescription());
            vo.setVersion(info.getVersion());
            vo.setStatus(info.getStatus());
            vo.setDocument(info.getDocument());
            // TODO 调用次数和平均时间暂时没有来源
            vo.setNumberOfCalls(0L);
            vo.setAverageResponseTime(0L);
            vo.setCreateTime(info.getCreateTime());
            vo.setServerId(info.getServerId());
            vo.setServerName(serverIdAndNameMap.get(info.getServerId()));
            return vo;
        }).collect(Collectors.toList());
        return getDataTable(voList);
    }

    @ApiOperation("导出接口信息列表")
    @PreAuthorize("@ss.hasPermi('gateway:interface:export')")
    @Log(title = "接口管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, GatewayInterfaceInfo gatewayInterfaceInfo)
    {
        List<GatewayInterfaceInfo> list = gatewayInterfaceInfoService.selectGatewayInterfaceInfoList(gatewayInterfaceInfo);
        ExcelUtil<GatewayInterfaceInfo> util = new ExcelUtil<GatewayInterfaceInfo>(GatewayInterfaceInfo.class);
        util.exportExcel(response, list, "接口管理数据");
    }

    @ApiOperation("获取接口详细信息")
    @PreAuthorize("@ss.hasPermi('gateway:interface:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        GatewayInterfaceInfoDetailedVO vo = new GatewayInterfaceInfoDetailedVO();

        GatewayInterfaceInfo gatewayInterfaceInfo = gatewayInterfaceInfoService.selectGatewayInterfaceInfoById(id);
        List<GatewayInterfaceLinkStrategy> linkList = gatewayInterfaceInfoService.selectGatewayInterfaceLinkStrategyByInterfaceIds(Collections.singleton(id));
        GatewayServer gatewayServer = gatewayServerService.selectGatewayServerById(gatewayInterfaceInfo.getServerId());
        List<GatewayStrategy> strategyList = gatewayStrategyService.selectGatewayStrategyByIds(linkList.stream().map(GatewayInterfaceLinkStrategy::getStrategyId).collect(Collectors.toSet()));

        vo.setId(gatewayInterfaceInfo.getId());
        vo.setInterfaceName(gatewayInterfaceInfo.getInterfaceName());
        vo.setInterfacePath(gatewayInterfaceInfo.getInterfacePath());
        vo.setRequestMethod(gatewayInterfaceInfo.getRequestMethod());
        vo.setDescription(gatewayInterfaceInfo.getDescription());
        vo.setVersion(gatewayInterfaceInfo.getVersion());
        vo.setStatus(gatewayInterfaceInfo.getStatus());
        vo.setDocument(gatewayInterfaceInfo.getDocument());
        // TODO 调用次数和平均时间暂时没有来源
        vo.setNumberOfCalls(0L);
        vo.setAverageResponseTime(0L);
        vo.setCreateTime(gatewayInterfaceInfo.getCreateTime());
        vo.setUpdateTime(gatewayInterfaceInfo.getUpdateTime());
        vo.setServerId(gatewayInterfaceInfo.getServerId());
        vo.setServerName(gatewayServer.getServerName());
        // 策略信息
        List<GatewayStrategyListVO> strategyListVOList = strategyList.stream().map(strategy -> {
                    GatewayStrategyListVO strategyListVO = new GatewayStrategyListVO();
                    strategyListVO.setId(strategy.getId());
                    strategyListVO.setStrategyName(strategy.getStrategyName());
                    strategyListVO.setStrategyType(strategy.getStrategyType());
                    strategyListVO.setDescription(strategy.getDescription());
                    strategyListVO.setStatus(strategy.getStatus());
                    return strategyListVO;
                })
                .collect(Collectors.toList());
        vo.setStrategyList(strategyListVOList);
        return success(vo);
    }

    @ApiOperation("新增接口信息")
    @PreAuthorize("@ss.hasPermi('gateway:interface:add')")
    @Log(title = "接口管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Validated @RequestBody InsertGatewayInterfaceInfoDTO dto)
    {
        return success(gatewayInterfaceInfoService.insertGatewayInterfaceInfoAndBindStrategy(dto));
    }

    @ApiOperation("修改接口信息")
    @PreAuthorize("@ss.hasPermi('gateway:interface:edit')")
    @Log(title = "接口管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody UpdateGatewayInterfaceInfoDTO dto)
    {
        return success(gatewayInterfaceInfoService.updateGatewayInterfaceInfoAndBindStrategy(dto));
    }

    @ApiOperation("删除接口信息")
    @PreAuthorize("@ss.hasPermi('gateway:interface:remove')")
    @Log(title = "接口管理", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(gatewayInterfaceInfoService.deleteGatewayInterfaceInfoByIds(ids));
    }

    @ApiOperation("启用/停用接口信息")
    @Log(title = "启用/停用接口信息", businessType = BusinessType.UPDATE)
    @PutMapping("/status")
    public AjaxResult updateStatus(@Validated @RequestBody UpdateDataStatusDTO dto)
    {
        return toAjax(gatewayInterfaceInfoService.updateGatewayInterfaceInfoStatusByIds(dto.getIds(), GatewayDataStatus.getByCode(dto.getStatus())));
    }

}
