now = now or 0	--当前时间
d = d or 0		--真实时间的偏移值

local Config = require("Config")
local Log = require("common.Log")
local Monitor = require("core.Monitor")
local ObjHuman = require("core.ObjHuman")
local JjcLogic = require("jjc.JjcLogic")
local FundLogic = require("present.FundLogic")
local LoginSignLogic = require("loginSign.LoginSignLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local MiddleHeartBeat = require("middle.MiddleHeartBeat")
local MiddleConnect = require("middle.MiddleConnect")
local DrillLogic = require("drill.DrillLogic")
local UnionWarMiddleLogic = require("union.UnionWarMiddleLogic")
local UnionWarLogic = require("union.UnionWarLogic")
local Util = require("common.Util")
local UnionDBLogic = require("union.UnionDBLogic")
local UnionLogic = require("union.UnionLogic")
local BattleLogic = require("battle.BattleLogic")
local CommonDB = require("common.CommonDB")
local UnionWarDBLogic = require("union.UnionWarDBLogic")
local ChatPaoMaLogic = require("chat.ChatPaoMaLogic")
local QQApi = require("platform.QQApi")
local ReportOnline = require("platform.ReportOnline")
local LianyuLogic = require("lianyu.LianyuLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local FcmLogic = require("fcm.FcmLogic")
local SharePlatformLogic = require("present.SharePlatformLogic")
local JjcGodWarLogic = require("jjcGodWar.JjcGodWarLogic")
local JjcLadderLogic = require("jjcLadder.JjcLadderLogic")
local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
local ValleyLogic = require("valley.ValleyLogic")
local YjTreasureLogic = require("yjTreasure.YjTreasureLogic")
local UnionWarLogic = require("union.UnionWarLogic")
local WarReportMiddle = require("warReport.WarReportMiddle")
local ZhanbuLogic = require("zhanbu.ZhanbuLogic")
local BillboardLogic = require("billboard.BillboardLogic")
local ChatRecord = require("chat.ChatRecord")
local HeroGrowUp = require("absAct.HeroGrowUp")
local AbsActLogic = require("absAct.AbsActLogic")
local MoZhuMiddleLogic = require("mozhu.MoZhuMiddleLogic")
local LostTempleLogic = require("lostTemple.lostTempleLogic")
local MainDianLogic = require("MaiDian.MaiDianLogic")
local VoucherShopLogic = require("voucher.VoucherShopLogic")
local ServerCommerceMiddle = require("serverCommerce.ServerCommerceMiddle")
local JjcNewLadderLogic = require("jjcnewladder.jjcNewLadderLogic")
local CycleActivityLogic = require("yunying.CycleActivity")
local commonOperate = require("core.commonOperate")
local GodsAreaCS = require("godsArea.GodsAreaCS")
local AreaBattleCS = require("areaBattle.AreaBattleCS")
local AnotherWorldBattleCS = require("anotherWorldBattle.AnotherWorldBattleCS")
local BaiZhanChengShenCS = require("baiZhanChengShen.BaiZhanChengShenCS")

register_timer = {    
	monitor = 60000,            -- 
    offlineCheck = 10000,       -- 离线校验 
    saveChar = 1000,            -- 用户存db
    onZhengDian = 15000, 
    humanRefresh = 10000,       -- 角色心跳刷新          
    middleHeartbeat = 3000,    
	dayCheck = 100,             -- 天检测
    unionOfflineCheck = 1000,   -- 公会会长离线时间检查
	paomaHerartbeat = 10000,    -- 跑马灯心跳
	tenSecond = 10000,			-- 10秒1次通用
    oneMin = 60000,             -- 60秒1次通用
    reportOnline = 300000,      -- 在线时长上报心跳
    fcm = 60000,                -- 防沉迷
    jjcGodWar = 2000,            -- 众神之战
    jjcLadder = 2000,           -- 天梯争霸
    valley = 2000,              -- 荣耀峡谷
    later = 1000,               -- 1秒1次 专门为了一些大数据量的处理延后处理用
}

LATER_DAYA = LATER_DAYA or {} -- {ts,func,param1, param2, param3, param4}


function monitor()
	print(_G.collectgarbage("count"))
	local humanCnt = ObjHuman.getOnlineCnt()
	Log.write(Log.LOGID_MONITOR, _G.collectgarbage("count"),  humanCnt)
	Monitor.output()       
end

function tenSecond()
    QQApi.onTimer()
end

function oneMin()
    MiddleConnect.onTimer()
    ZhanbuLogic.checkRecover()

    AreaBattleCS.oneMin()
    AnotherWorldBattleCS.oneMin()
    BaiZhanChengShenCS.oneMin()
end

function offlineCheck()
	_G.collectgarbage("step", 100000)
	ObjHuman.humanOfflineCheck()        
end

function saveChar()
	ObjHuman.saveCharDB()        
end

function humanRefresh()
    ObjHuman.refresh()
end

function doZhengDian(hour)
   -- 整点的时候刷新逻辑用的内存较多 这里gc一把
    _G.collectgarbage("step", 100000)

    if hour == 0 then
        YjTreasureLogic.onZero()
        CycleActivityLogic.onZero()
        YunYingLogic.onZero()
        for _, human in pairs(ObjHuman.onlineUuid) do
            ObjHuman.updateDaily(human)
            YunYingLogic.onZeroHuman(human)
            DailyTaskLogic.onLogin(human)
        end    
        UnionLogic.onHour()
        LianyuLogic.onZero()
        SharePlatformLogic.onZero()
        WarReportMiddle.onZero()
        BillboardLogic.onZero()
        ChatRecord.CHAT_RECORD_REPETITION = {}
        local expireTs = os.time() - 86400
        if DELIVER_CODE_HIS then
            for k, v in pairs(DELIVER_CODE_HIS) do
                if v < expireTs then DELIVER_CODE_HIS[k] = nil end
            end
        end
        if CHARGE_CODE_HIS then
            for k, v in pairs(CHARGE_CODE_HIS) do
                if v < expireTs then CHARGE_CODE_HIS[k] = nil end
            end
        end
        HeroGrowUp.actLoop()
        -- LostTempleLogic.onZero()
	    VoucherShopLogic.VoucherShop_OnZero()
        MainDianLogic.MaiDian_OnTime()
        ServerCommerceMiddle.CommerceMiddle_OnZero()

        commonOperate.onZero()
    end

    GodsAreaCS.onHour(hour)
    AreaBattleCS.onHour(hour)
    AnotherWorldBattleCS.onHour(hour)
    BaiZhanChengShenCS.onHour(hour)
    --if hour == 21 then
    --    if _G.is_middle ~= true then 
    --        JjcLogic.onHour(hour)
    --    end
    --end
    JjcLogic.onHour(hour)
    JjcNewLadderLogic.onHour(hour)

    
    if hour == 2 then
        local weekDay = Util.getWeekDay()
        if weekDay == 2 then
            -- 每周一凌晨2點 斷開鏈接 并且重新取一下php的跨服信息 重新連新跨服            
            MiddleConnect.autoResetMiddle()
        end
    end


    YunYingLogic.onHour(hour)
    UnionWarDBLogic.onHour(hour)
    AbsActLogic.onHour(hour)
    MoZhuMiddleLogic.onHour(hour)
    
    -- 晚上11点检查美团2楼玩家每日固定奖励领取情况
    if hour == 23 then
        local ZhuanpanLogic = require("zhuanpan.ZhuanpanLogic")
        ZhuanpanLogic.checkMtFrom2floorDailyReward()
    end
    
    _G.collectgarbage("step", 100000)
end

lastUpDateTime = lastUpDateTime or nil
function onZhengDian()
	if lastUpDateTime and (now - lastUpDateTime) < 180000 or 120000 < now % (1000 * 60 * 60) then
		return
    end
    lastUpDateTime = now
        
    local hour = os.date("%H", math.floor(now / 1000)) + 0
    print("onZhengDian", hour)
	
	
    Log.write(Log.LOGID_MONITOR, _G.collectgarbage("count"),  'gc befor')
    _G.collectgarbage("collect")
    Log.write(Log.LOGID_MONITOR, _G.collectgarbage("count"),  'gc after')
 
    doZhengDian(hour)
end

function dayCheck()
	local call = 1
	local now = os.time()
	local resetTime = CommonDB.getResetTime()
    if resetTime == 0 then	
		CommonDB.setResetTime(now)
		return
    end
	
	if call == 1 then
        local sameDay = Util.isSameDay(resetTime, now)
        call = sameDay == nil and 0 or 1
	end
	
	if call == 0 then
		CommonDB.setResetTime(now)
        DrillLogic.dayCheck()	
	end	
end

function middleHeartbeat()
   MiddleHeartBeat.heartbeat()
end

function unionOfflineCheck()
    UnionLogic.onTimer()
end

function paomaHerartbeat()
	ChatPaoMaLogic.onTimer()
end

function reportOnline()
    ReportOnline.onTimer()
end

function fcm()
    FcmLogic.onTimer()
end

function jjcGodWar()
    JjcGodWarLogic.onTimer()
end

function jjcLadder()
    JjcLadderLogic.onTimer()
end

function valley()
    ValleyLogic.onTimer()
end

function later()
    if LATER_DAYA[1] == nil then
        return
    end
    
    local tempData = LATER_DAYA[1]
    local now = os.time()
    local ts = tempData.ts
    if ts <= now then
        table.remove(LATER_DAYA, 1)
        tempData.func(tempData.param1, tempData.param2, tempData.param3, tempData.param4)
    end
end

last_exe_time = last_exe_time or {}
function handlerTime(msec)
    now = msec + d
    if not register_timer[last_exe_func] then
        last_exe_func = nil
    end
    local tmp = last_exe_func
    while true do   
        local k, v = next(register_timer, last_exe_func)
        if not k then
            k, v = next(register_timer)
        end
        if not k then
            return
        end
       
        last_exe_func = k

        local last_time = last_exe_time[k]
        if last_time then
            if last_time + v <= now then
                last_exe_time[k] = now
                Monitor.handleTimer(_ENV[k], now - last_time, k)               
                break
            end
        else
            last_exe_time[k] = now
            break
        end
        if k == tmp then
            return
        end
    end
end

local function cmpLater(a, b)
    return a.ts < b.ts
end

function addLater(laterSec, func, param1, param2, param3, param4)
    local tempData = {}
    tempData.ts = os.time() + laterSec
    tempData.func = func
    tempData.param1 = param1
    tempData.param2 = param2
    tempData.param3 = param3
    tempData.param4 = param4
    table.insert(LATER_DAYA, tempData)
    table.sort(LATER_DAYA, cmpLater)
end
