package com.ruoyi.interfaces.service.impl;

import com.ruoyi.interfaces.domain.PtApp;
import com.ruoyi.interfaces.domain.PtService;
import com.ruoyi.interfaces.domain.PtServiceLog;
import com.ruoyi.interfaces.service.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author LinQiLong
 * @date 4/6/2022 9:33 AM
 */
@Service
public class InterfaceAuthServiceImpl implements InterfaceAuthService {

    @Autowired
    private InterfaceTokenService tokenService;

    @Autowired
    private PtServiceApplyService ptServiceApplyService;

    @Autowired
    private PtServiceService ptServiceService;


    @Autowired
    private PtAppService appService;

    @Override
    public Map<String, Object> authCheck(String srvId, String token) {
        Map<String, Object> ret = new HashMap<>(3);
        PtService ptService = ptServiceService.get(srvId);
        if (ptService == null) {
            ret.put("status", false);
            ret.put("code", 4001);
            ret.put("msg", "url 异常！");
            return ret;
        }

        String openCndtn = Optional.ofNullable(ptService.getOpenCndtn()).orElse("0");
        String appId = "";
        switch (openCndtn) {
            case "2":
                //完全开放
                break;
            case "1":
                //登录开放
                ret = checkToken(token);
                if (!MapUtils.getBoolean(ret, "status", false)) {
                    return ret;
                }

                appId = MapUtils.getString(ret, "appId");
                break;
            case "0":
            default:
                //申请开放
                ret = checkToken(token);
                if (!MapUtils.getBoolean(ret, "status", false)) {
                    return ret;
                }
                appId = MapUtils.getString(ret, "appId");
                if (!ptServiceApplyService.checkAuth(appId, srvId)) {
                    ret.put("status", false);
                    ret.put("code", 4004);
                    ret.put("msg", "应用无权限访问服务！");
                    ret.put("data", null);
                    return ret;
                }
                break;
        }

        ret.put("status", true);
        ret.put("msg", "success");
        ret.put("url", ptService.getUrl());

        // 更新服务调用次数
        updateCnt(ptService);
        recordLog(ptService, appId);
        return ret;
    }

    private Map<String, Object> checkToken(String token) {
        Map<String, Object> ret = new HashMap<>(3);
        //第一步：校验token，如果为空，则跳到403页面上。
        if (StringUtils.isBlank(token)) {
            ret.put("status", false);
            ret.put("code", 4002);
            ret.put("msg", "token为空！");
            return ret;
        }

        // 根据token获取相应的appId，进行校验
        String appId = tokenService.getAppIdFromToken(token);
        if (StringUtils.isBlank(appId)) {
            ret.put("status", false);
            ret.put("code", 4003);
            ret.put("msg", "token已失效，请重新请求token！");
            return ret;
        }

        ret.put("status", true);
        ret.put("appId", appId);
        return ret;
    }

    /**
     * 更新服务调用次数
     *
     * @param ptService 服务信息
     */
    private void updateCnt(PtService ptService) {
        PtService service = new PtService();
        service.setSrvId(ptService.getSrvId());
        service.setCnt(ptService.getCnt() + 1);
        ptServiceService.update(service);
    }

    /**
     * 记录日志
     *
     * @param ptService 服务
     * @param appId     用户的应用ID
     */
    private void recordLog(PtService ptService, String appId) {
        /*PtApp app = appService.get(appId);
        PtServiceLog serviceLog = new PtServiceLog();
        serviceLog.setSrvMethod(ptService.getRqtype());
        serviceLog.setSrvId(ptService.getSrvId());
        serviceLog.setSrvUrl(ptService.getUrl());
        serviceLog.setName(ptService.getName());
        Optional.ofNullable(app).ifPresent(a -> {
            serviceLog.setAppName(a.getAppName());
        });
        serviceLog.setAppId(appId);
        serviceLog.setSttm(new Date());
        logService.insert(serviceLog);*/
    }

}
