import base64, subprocess, sys, os, textwrap

src = sys.argv[1]
remote = sys.argv[2]
token = sys.argv[3]

data = base64.b64encode(open(src, 'rb').read()).decode()
chunk = 30000
parts = [data[i:i+chunk] for i in range(0, len(data), chunk)]

def run(lua, timeout=120):
    p = subprocess.run(["python3", "/opt/ws-remote/relayctl.py", "exec", lua,
                        "--timeout", str(timeout), "--token", token],
                       capture_output=True, text=True)
    return p.stdout.strip() + p.stderr.strip()

print(run('if isfile("%s.b64") then delfile("%s.b64") end print("cleared")' % (remote, remote)))
for i, part in enumerate(parts):
    lua = 'appendfile("%s.b64", "%s")' % (remote, part)
    out = run(lua)
    if "finished" not in out:
        print("chunk", i, "failed:", out)
        sys.exit(1)
print("uploaded", len(parts), "chunks,", len(data), "b64 bytes")
lua = '''
local b64 = readfile("%s.b64")
local map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local out, buf, n = {}, 0, 0
for i = 1, #b64 do
    local v = map:find(b64:sub(i, i), 1, true)
    if v then
        n = n + 1; buf = buf * 64 + (v - 1)
        if n == 4 then
            out[#out+1] = string.char(bit32.rshift(buf, 16) %% 256, bit32.rshift(buf, 8) %% 256, buf %% 256)
            buf, n = 0, 0
        end
    end
end
writefile("%s", table.concat(out))
print("wrote", #table.concat(out), "bytes")
''' % (remote, remote)
print(run(lua))
