//接口任务 定期更新

import { INTERFACErEQUESTTYPEENUM } from "../../config/enum";
import { Config } from "../../config/interfaceConfig";
import { BizError } from "../../util/bizError";
import { get, post, postForm } from "../../util/request";

//初始化接口数据
export async function initInterfaceData() {
    const InitTaskSuccess = await taskUpdate();
    if (!InitTaskSuccess) throw new BizError("服务器启动失败: 初始化定时接口数据时出现问题 请检查目标服务器或本地请求配置");
    const InitRealTimeSuccess = await initRealTime();
    if (!InitRealTimeSuccess) throw new BizError("服务器启动失败: 初始化实时接口数据时出现问题 请检查目标服务器或本地请求配置");
    console.log("初始化接口数据成功");
    setInterval(() => {
        taskUpdate();
    }, 10000);
}


//异常接口 不更新数据
let errorInterfaceInfo = {};

//定时接口 数据更新情况
let updateInfo = {
    "接口名称":{lastTime:0, updateUseTime:0},//使用时间是毫秒
};

//定时接口 缓存数据
let dataQueue = {};

async function taskUpdate() {
    let thisTaskInfo = [];//此次任务
    let defaultUseTime =  60000;

    let thisTime = new Date().valueOf();

    let initSuccess = true;

    for (let interfaceName in Config) {
        const LastReqError = errorInterfaceInfo[interfaceName];
        if (LastReqError) {
            console.log(`${interfaceName} 请求时出现过 ${LastReqError} 异常 保险起见此次更新不再请求`);
            continue;
        }

        const ThisConfig = Config[interfaceName];
        if (ThisConfig.type == INTERFACErEQUESTTYPEENUM.即时更新) continue;

        let lastTaskInfo = updateInfo[interfaceName];
        if ( !lastTaskInfo ) thisTaskInfo.push({name:defaultUseTime, useTime:defaultUseTime});
        else if ( lastTaskInfo && (thisTime - lastTaskInfo) > ThisConfig.time ) {
            thisTaskInfo.push({name:defaultUseTime, useTime:lastTaskInfo.updateUseTime});
        }
        defaultUseTime += 1;
    }
    thisTaskInfo.sort((a, b) => {return a.useTime - b.useTime});//耗时短的优先

    for (let i = 0; i < thisTaskInfo.length; i++) { //更新数据
        let {name} = thisTaskInfo[i];
        const ThisConfig = Config[name];
        const StartTime = new Date().valueOf();
        
        let reqRes;
        switch(ThisConfig.reqType) {
            case "get": reqRes = await get(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "post": reqRes = await post(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "postForm": reqRes = await postForm(ThisConfig.url, ThisConfig.body); break;
        }
        const UseTime = new Date().valueOf() - StartTime;
        if (reqRes.success) {
            if (!updateInfo[name]) updateInfo[name] = {lastTime:thisTime, updateUseTime:UseTime};
            else {
                updateInfo[name].lastTime = thisTime;
                updateInfo[name].updateUseTime = UseTime;
            }
            if (dataQueue[name]) delete dataQueue[name];
            dataQueue[name] = JSON.stringify(reqRes.body);//放入缓存
        } else {
            let errorMsg = reqRes.message;
            if (reqRes.message && reqRes.message.code == "ESOCKETTIMEDOUT") errorMsg = "超时";
            console.log(`接口 ${name} 请求失败 失败原因${errorMsg}`);
            if (["404", "503"].indexOf(errorMsg) > -1) { //下次不再请求
                errorInterfaceInfo[name] = errorMsg;
            }
            initSuccess = false;
        }
    }
    return initSuccess;
}


//即时数据缓存 当请求失败时会用到这里的数据
let realTimeDataQueue = {};

//即时数据初始化
export async function initRealTime() {
    let initSuccess = true;
    for (let interfaceName in Config) {
        const ThisConfig = Config[interfaceName];
        if (ThisConfig.type == INTERFACErEQUESTTYPEENUM.定时更新) continue;
        let reqRes;
        switch(ThisConfig.reqType) {
            case "get": reqRes = await get(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "post": reqRes = await post(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "postForm": reqRes = await postForm(ThisConfig.url, ThisConfig.body); break;
        }
        if (!reqRes.success) {
            console.log(`${interfaceName} 接口请求失败 请求地址为 ${ThisConfig.url} 失败原因 ${reqRes.message}`);
            initSuccess = false;
        }
        realTimeDataQueue[interfaceName] = reqRes.data;
    }
    return initSuccess;
}

export async function getInterfaceByInterfaceName(name) {
    const ThisConfig = Config[name];
    let data:any;
    if (ThisConfig.type == INTERFACErEQUESTTYPEENUM.即时更新) {
        let reqRes;
        switch(ThisConfig.reqType) {
            case "get": reqRes = await get(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "post": reqRes = await post(ThisConfig.url, ThisConfig.body, ThisConfig.header); break;
            case "postForm": reqRes = await postForm(ThisConfig.url, ThisConfig.body); break;
        }
        if (reqRes.success) {
            data = reqRes.data;
        } else {
           data = realTimeDataQueue[name];
           console.log(`${name}请求失败, 读取缓存数据`);
        }
        
    } else data = dataQueue[name];
    
    return data;
}

