local NetworkManager = {}

--[[
    1. 心跳包要隔一段时间发送一次
    2. 两个周期没有收到返回消息 弹出提示 断线重连
]]

local function ConnectServer(serverIP, serverPort)
    local connectState = CS.LuaSocketManager.Connect(serverIP, serverPort)
    NetworkManager.connectState = connectState
    return connectState
end

local function ConnectLogicCoroutine()
    print("----> ConnectLogicCoroutine:")

    local serverIP = "192.168.1.85"
    local serverPort = 9305

    local eventManager = require("Base/ZEventDispatchCenter.lua")
    require("Base/CoroutineHelper.lua"):WaitForEndOfFrame()

    local hasFailed = false
    local condition = false
    while condition == false do
        local connectState = SafeCall(ConnectServer, serverIP, serverPort)
        NetworkManager.connectState = connectState

        if not connectState then
			print(string.format(
				"NetworkManager.ConnectLogicCoroutine ConnectServer(%s:%s) Failed. Retry after 5s:",
				serverIP, serverPort, connectState
			))
            eventManager:DispatchEvent(eventManager.EventType.NET_CONNECT_STATE, false)
            hasFailed = true
            require("Base/CoroutineHelper.lua"):Wait(5)
        end
        condition = connectState == true
    end

    print(string.format( "NetworkManager.ConnectLogicCoroutine ConnectServer(%s:%s) Success!", serverIP, serverPort))
    if hasFailed == true then
	    -- todo
        -- local languageConfig = require("Config/SConfigManager.lua"):GetConfig("languageConfig")
        -- ShowDialogOK(languageConfig["login"]["connect_success"])
        -- eventManager:DispatchEvent(eventManager.EventType.NET_CONNECT_STATE, true)
    end

    require("Network/NetworkQueue.lua"):Reset()
end

local function RecvlogicCoroutine()
    while true do
		require("Base/CoroutineHelper.lua"):Wait(0.1)
        local connectState = CS.LuaSocketManager.Update()
        -- todo 待办
        if not connectState then
            -- 断线重连
            return
        end

		local serverMessage = CS.LuaSocketManager.RecvMessage()
		if serverMessage ~= "" and serverMessage ~= nil then
			local serverProtocol = NetworkManager._jsonConvert:decode(serverMessage)
			local processorName = serverProtocol.msgType
            print("----> processorName:", processorName)
			if not processorName then print("Get processorName Failed for: ", serverMessage) end

			local msgType = NetworkManager._s2c[serverProtocol.msgType]
			if not msgType then print("Get msgType failed for : " , serverMessage) end

            local NetworkQueue = require("Network/NetworkQueue.lua")
            NetworkQueue:PushMsgOnRecv(tonumber(serverProtocol.uid), serverProtocol)

            -- local data = NetworkQueue:TryPopMsg()
            -- while data ~= nil do
            --     local func = NetworkManager._s2c[data.msgType]
            --     func(NetworkManager._s2c, data)
            --     data = NetworkQueue:TryPopMsg()
            -- end

            msgType(NetworkManager._s2c, serverProtocol)
		end
	end
end

local function HeartBeatCoroutine()
    local nMaxCount = 3
    local eventManager = require("Base/ZEventDispatchCenter.lua")

    while true do
        require("Network/C2S.lua"):HeartBeat()

        require("Base/CoroutineHelper.lua"):Wait(10)
        local nHeartBeat = GetCache("HEART_BEAT", 0)
        nHeartBeat = nHeartBeat + 1

        if nHeartBeat >= nMaxCount then
            require("Base/CoroutineHelper.lua"):Stop(NetworkManager._heartBeatCorutine)
            -- todo 用户掉线
        end
    end
end

function NetworkManager:Init()
    print("NetworkManager.Init~")

    self._c2s = require("Network/C2S.lua")
    self._s2c = require("Network/S2C.lua")

    self._connectLogicCoroutine = require("Base/CoroutineHelper.lua"):Start(ConnectLogicCoroutine)

    self._recvlogicCoroutine    = require("Base/CoroutineHelper.lua"):Start(RecvlogicCoroutine)
    self._jsonConvert           = require("Base/json.lua")

    -- todo for test: 测试环节暂时不做心跳
    -- self._heartBeatCorutine  = require("Base/CoroutineHelper.lua"):Start(HeartBeatCoroutine)
end

function NetworkManager:UnInit()
    require("Base/CoroutineHelper.lua"):Stop(NetworkManager._connectLogicCoroutine)
    require("Base/CoroutineHelper.lua"):Stop(NetworkManager._recvlogicCoroutine)
    -- require("Base/CoroutineHelper.lua"):Stop(NetworkManager._heartBeatCorutine)
    print("NetworkManager.UnInit ~")
end

function NetworkManager:RemoteCall(funcName, ... )
    print("NetworkManager:RemoteCall funcName:", funcName, " param:", ...)
	self._c2s:RemoteCall(funcName, ...)
end

function NetworkManager:EnterMeeting(meetingId, tel, szNick)
    if not self.connectState then
        print("Network is not ready.");
        return
    end

    self._c2s:EnterMeeting(meetingId, tel, szNick)
end

function NetworkManager:GetScreenInfo(meetingId)
    print("----> NetworkManager:GetScreenInfo, meetingId:", meetingId)
    if not self.connectState then
        print("Network is not ready.");
        return
    end

    -- todo: 龙哥暂时没给文档
    self._c2s:GetScreenInfo(meetingId)
end

return NetworkManager