local posts = KEYS[1]
local update_desc = cjson.decode(ARGV[2])
local post = cjson.decode(redis.call("HGET", posts, ARGV[1]))

local delete_keys = {}
local delete_kvs = {}
local add_keys = {}

if update_desc.replace ~= nil then
    for k, v in pairs(update_desc.replace) do
        table.insert(delete_keys, k)
        add_keys[k] = v
    end
end
if update_desc.delete ~= nil then
    if update_desc.delete[0] == nil then
        -- Table has string keys. Probably!
        for k, v in pairs(update_desc.delete) do
            delete_kvs[k] = v
        end
    else
        -- Table has numeric keys. Probably!
        for i, v in ipairs(update_desc.delete) do
            table.insert(delete_keys, v)
        end
    end
end
if update_desc.add ~= nil then
    for k, v in pairs(update_desc.add) do
        add_keys[k] = v
    end
end

for i, v in ipairs(delete_keys) do
    post["properties"][v] = nil
    -- TODO delete URL links
end

for k, v in pairs(delete_kvs) do
    local index = -1
    if k == "children" then
        for j, w in ipairs(post[k]) do
            if w == v then
                index = j
                break
            end
        end
        if index > -1 then
            table.remove(post[k], index)
        end
    else
        for j, w in ipairs(post["properties"][k]) do
            if w == v then
                index = j
                break
            end
        end
        if index > -1 then
            table.remove(post["properties"][k], index)
            -- TODO delete URL links
        end
    end
end

for k, v in pairs(add_keys) do
    if k == "children" then
        if post["children"] == nil then
            post["children"] = {}
        end
        for i, w in ipairs(v) do
            table.insert(post["children"], 1, w)
        end
    else
        if post["properties"][k] == nil then
            post["properties"][k] = {}
        end
        for i, w in ipairs(v) do
            table.insert(post["properties"][k], w)
        end
        if k == "url" then
            redis.call("HSET", posts, v, cjson.encode({ see_other = post["properties"]["uid"][1] }))
        elseif k == "channel" then
            local feed = cjson.decode(redis.call("HGET", posts, v))
            table.insert(feed["children"], 1, post["properties"]["uid"][1])
            redis.call("HSET", posts, v, cjson.encode(feed))
        end
    end
end

local encoded = cjson.encode(post)
redis.call("SET", "debug", encoded)
redis.call("HSET", posts, post["properties"]["uid"][1], encoded)
return