#!/bin/lua

local version = "1.6.0"
local api = os.getenv("VERSION") or getAppProperty("MIDlet-Version")
local server = os.getenv("REPO") or "http://opentty.fun"

local function load_sources()
    local ok, sources = pcall(load, io.read("/etc/sources"))
    if not ok then
        error(":: failed to load sources: " .. tostring(sources))
    end
    return sources.version, sources.mirror
end

local db_version, mirror = load_sources()

os.setproc("name", "pkg")

if arg[1] == "install" then
    if os.getuid() ~= 0 then
        print(":: must be root to install packages")
        os.exit(1)
    end

    for i = 2, #arg do
        local pkg_name, err = arg[i], nil
        local pkg = mirror[pkg_name]

        if pkg then
            if pkg.riscv == true then
                if java.midlet.lite ~= false then
                    print(":: package " .. pkg_name .. " requires the full OpenTTY ARM build")
                    os.exit(69)
                end
            end
            if pkg.depends then
                for _, dep in ipairs(pkg.depends) do
                    local dep_pkg = mirror[dep]
                    if not dep_pkg then
                        print(":: dependency " .. dep .. " not found for package " .. pkg_name)
                        os.exit(1)
                    end
                    print(":: installing dependency " .. dep)
                    local url = server .. "/apps/" .. db_version .. "/" .. dep_pkg.remote
                    
                    local ok, stream = pcall(socket.http.rget, url)
                    if ok then
                        ok, err = pcall(io.copy, stream, dep_pkg.here)
                        if not ok then
                            print(":: error installing dependency " .. dep .. ": " .. tostring(err))
                            os.exit(1)
                        else
                            print(":: installed dependency " .. dep)
                        end
                    else
                        print(":: error downloading dependency " .. dep .. ": " .. tostring(stream))
                        os.exit(1)
                    end
                end
            end
            print(":: downloading " .. pkg_name .. " from " .. pkg.remote)

            local url = server .. "/apps/" .. db_version .. "/" .. pkg.remote
            
            local ok, stream = pcall(socket.http.rget, url)
            if ok then
                ok, err = pcall(io.copy, stream, pkg.here)
                if not ok then
                    print(":: error installing " .. pkg_name .. ": " .. tostring(err))
                else
                    print(":: installed " .. pkg_name)
                end
            else
                print(":: error downloading " .. pkg_name .. ": " .. tostring(stream))
            end
        else print(":: package " .. pkg_name .. " not found") end
    end
elseif arg[1] == "remove" then
    if os.getuid() ~= 0 then
        print(":: must be root to remove packages")
        os.exit(1)
    end

    for i = 2, #arg do
        local pkg_name = arg[i]
        local pkg = db.mirror[pkg_name]

        if pkg then
            print(":: removing " .. pkg_name)
            local ok, err = pcall(os.remove, pkg.here)
            if not ok then
                print(":: error removing " .. pkg_name .. ": " .. tostring(err))
            else
                print(":: removed " .. pkg_name)
            end
        else
            print(":: package " .. pkg_name .. " not found")
        end
    end

elseif arg[1] == "download" then
    if arg[2] and arg[3] then
        print(":: downloading " .. arg[2] .. " to " .. arg[3])
        local pkg_name = arg[2]
        local pkg = mirror[pkg_name]

        if pkg then
            local url = server .. "/apps/" .. db_version .. "/" .. pkg.remote
            
            local ok, stream = pcall(socket.http.rget, url)
            if ok then
                ok, err = pcall(io.copy, stream, arg[3])
                if not ok then
                    print(":: error downloading " .. pkg_name .. ": " .. tostring(err))
                else
                    print(":: downloaded " .. pkg_name .. " to " .. arg[3])
                end
            end
        else
            print(":: package " .. pkg_name .. " not found")
        end
    else
        print(":: usage: pkg download <package> <destination>")
        os.exit(2)
    end
elseif arg[1] == "update" then
    if os.getuid() ~= 0 then
        print(":: must be root to update package database")
        os.exit(1)
    end

    local url = server .. "/apps/" .. api .. "/sources.lua"
    
    local ok, body = pcall(socket.http.get, url)
    if ok then
        ok, err = pcall(io.write, body, "/etc/sources")
        if not ok then
            print(":: error updating package database: " .. tostring(err))
        else
            print(":: package database updated")
        end
    end
elseif arg[1] == "switch" then
    if os.getuid() ~= 0 then
        print(":: must be root to switch package database")
        os.exit(1)
    end
    if arg[2] == nil then
        print(":: usage: pkg switch <version>")
        os.exit(2)
    end

    local url = server .. "/apps/" .. arg[2] .. "/sources.lua"
    
    local ok, body = pcall(socket.http.get, url)
    if ok then
        ok, err = pcall(io.write, body, "/etc/sources")
        if not ok then
            print(":: error switching package database: " .. tostring(err))
        else
            print(":: package database switched to version " .. arg[2])
        end
    else print(":: error switching package database: " .. tostring(stream)) end
elseif arg[1] == "list" then
    print(":: available packages (" .. #mirror .. "):")
    for pkg_name, pkg in pairs(mirror) do
        print(pkg_name .. " - " .. pkg.description)
    end
elseif arg[1] == "version" then
    print(":: pkg version " .. version)
    print(":: sources for OpenTTY ".. db_version)
else
    print(":: usage: pkg <command> [args]")
    print(":: commands:")
    print("   install <package> - install a package")
    print("   remove <package> - remove a package")
    print("   update - update the package database")
    print("   switch <version> - switch to a different package database version")
    print("   list - list available packages")
    print("   version - show version")
end
