local NetworkManager = {}

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

local function ConnectLogicCoroutine()
    local serverIP = "127.0.0.1"
    local serverPort = 25500

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

    local hasFailed = false
    local condition = false
    while condition == false do
        local connectState = SafeCall(ConnectServer, serverIP, serverPort)
        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(3)
        end
        condition = connectState == true
    end

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

local function RecvlogicCoroutine()
    while true do
		require("Base/CoroutineHelper.lua"):Wait(0.1)
		local serverMessage = CS.ProjectNine.STCPConnecter.RecvMessage()
		if serverMessage ~= "" then
			local serverProtocol = NetworkManager._jsonConvert:decode(serverMessage)
			local processorName = serverProtocol.fnProcessor
			if not processorName then print("Get processorName Failed for: ", serverMessage); end

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

            fnProcessor(NetworkManager._s2c, table.unpack(serverProtocol.tParam))
		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")
end

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

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

function NetworkManager:ApplyTestBattle()
	self._c2s:ApplyTestBattle()
end

function NetworkManager:Login(account, password)
    if not self.connectState then
        print("Network is not ready.");
        return
    end

    print("NetworkManager.Login ->", account, password)
    self._c2s:Login(account, password)
end

function NetworkManager:ModifyPlayerName(newName)
    if not self.connectState then
        print("Network is not ready.")
        return
    end

    print("NetworkManager.ModifyPlayerName ->", newName)
    self._c2s:ModifyPlayerName(newName)
end

return NetworkManager