local function split(inputstr, sep)
    if sep == nil then
        sep = "%s"
    end
    local t={} ; local i=1
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end

local function getNewX(point, dir, coloumns)
    local pt = tonumber(point)
    local d = tonumber(dir)
    pt = point + d

    if pt >= coloumns then
        pt = pt - coloumns
    elseif pt < 0 then
        pt = pt + coloumns
    end
    return pt
end

local result        = {}
local matchId       = ARGV[1]
local rowNo         = ARGV[2]
local coloumns      = tonumber(ARGV[3])
local curTimeStamp  = tonumber(ARGV[4])

local lastUpdated = tonumber(redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "LASTUPDATE"))
local speed       = tonumber(redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "rowSpeed"))
table.insert(result, rowNo)                         -- row number
if ( speed and speed > 0 and curTimeStamp - lastUpdated >= speed ) then
    table.insert(result, 1)                         -- updated
    local newTime = lastUpdated + speed
    redis.call("HSET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "LASTUPDATE", newTime)
    local pos       =   redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "mapPieces")
    local direction =   redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "rowDirection")

    local newPos    =   ""
    local posArray  =   split(pos, "_")
    table.insert(result, table.getn(posArray))        -- length of enemies
    table.insert(result, newTime)                -- time stamp of update
    for i =1, table.getn(posArray) , 1
    do
        local localResult = {}
        local singleEnemy = split(posArray[i], ":")
        local nextPos = getNewX(singleEnemy[1], direction, coloumns)
        local playerPosA = redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:1", "map:" .. nextPos .. ":" .. rowNo)
        local playerPosB = redis.call("HGET", "BATTLES:MATCH:{" .. matchId .. "}:2", "map:" .. nextPos .. ":" .. rowNo)
        table.insert(localResult, nextPos .. ":" .. singleEnemy[table.getn(singleEnemy)])   -- to be added : deleted
        redis.call("HSET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "map:" .. nextPos, 1000)
        redis.call("HDEL", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "map:" .. singleEnemy[table.getn(singleEnemy)])

        table.insert(localResult, playerPosA)            -- if playerA is there
        table.insert(localResult, playerPosB)            -- if playerB is there
        newPos = newPos .. nextPos

        for j =1, table.getn(singleEnemy) - 1, 1
        do
            newPos = newPos .. ":" .. singleEnemy[j]
        end

        table.insert(result, localResult)               -- insert local into main result

        if i == table.getn(posArray) then
            table.insert(result, newPos)                -- new final pos of enemy
            redis.call("HSET", "BATTLES:MATCH:{" .. matchId .. "}:row:" .. rowNo, "mapPieces", newPos)
        else
            newPos = newPos .. "_"
        end

    end
else
    table.insert(result, 0)
end

return result
