local socket = require 'socket'
local crypt = require "skynet.crypt"

local function encode_token(token)
    return string.format("%s@%s:%s:%s", crypt.base64encode(token.user), crypt.base64encode(token.worldId),
        crypt.base64encode(token.pass), crypt.base64encode(token.pf))
end

local token = {
    pf = '1010',
    user = 'teefe',
    pwd = '123456789',
    worldId = 1,
}

return function(login_host, login_port)
    local sock = socket.connect(login_host or '127.0.0.1', login_port or 9527)
    local challenge = crypt.base64decode(sock:receive('*l'))
    local clientkey = crypt.randomkey()
    sock:send(crypt.base64encode(crypt.dhexchange(clientkey)) .. '\n')

    local line = crypt.base64decode(sock:receive '*l')
    local secret = crypt.dhsecret(line, clientkey)

    local hmac = crypt.hmac64(challenge, secret)
    -- 5. 回应服务器的握手挑战码，确认握手正常
    sock:send(crypt.base64encode(hmac) .. '\n')

    -- 6. DES加密发送 token串
    local etoken = crypt.desencode(secret, encode_token(token))
    sock:send(crypt.base64encode(etoken) .. '\n')
    -- 服务器解密后调用定制的auth和login handler处理客户端请求

    -- 7. 从服务器读取 登录结果： 状态码 和subid
    local result = sock:receive '*l'
    local code = tonumber(string.sub(result, 1, 3))
    assert(code == 200, "auth error:" .. tostring(code))
    sock:close()

    local substr = crypt.base64decode(string.sub(result, 5))
    local ip, port, uid, subid = substr:match("([^:]+):([^:]+)@([^@]+)@(.+)")
    return {
        ip = ip,
        port = port,
        uid = uid,
        worldId = token.worldId,
        secret = secret,
        subid = subid,
    }
end
