local files = {
    {
        url    = "https://lookup.andre601.ch/assets/v2.2/config.lua",
        backup = "https://codeberg.org/Andre601/trainlookup-pages/raw/branch/pages/assets/v2.2/config.lua",
        path   = "/config.lua"
    },
    {
        url    = "https://lookup.andre601.ch/assets/v2.2/startup.lua",
        backup = "https://codeberg.org/Andre601/trainlookup-pages/raw/branch/pages/assets/v2.2/startup.lua",
        path   = "/startup.lua"
    },
    {
        url    = "https://lookup.andre601.ch/assets/v2.2/trainutils.lua",
        backup = "https://codeberg.org/Andre601/trainlookup-pages/raw/branch/pages/assets/v2.2/trainutils.lua",
        path   = "/trainutils.lua"
    },
    {
        url    = "https://lookup.andre601.ch/assets/v2.2/texthelper.lua",
        backup = "https://codeberg.org/Andre601/trainlookup-pages/raw/branch/pages/assets/v2.2/texthelper.lua",
        path   = "/texthelper.lua"
    },
    {
        url    = "https://lookup.andre601.ch/assets/v2.2/uninstaller.lua",
        backup = "https://codeberg.org/Andre601/trainlookup-pages/raw/branch/pages/assets/v2.2/uninstaller.lua",
        path   = "/uninstaller.lua"
    }
}

local w, h = term.getSize()

-- =================
--   Utility stuff
-- =================

local function clamp(v, min, max)
    if v < min then return min end
    if v > max then return max end
    return v
end

local function makeBar(percent, width)
    percent = clamp(percent, 0, 100)

    local filled = math.floor((percent / 100) * width)
    local empty = width - filled

    return string.rep("|", filled) .. string.rep(" ", empty)
end

local function truncate(text, maxLen)
    if #text <= maxLen then
        return text
    end

    if maxLen <= 3 then
        return string.sub(text, 1, maxLen)
    end

    return string.sub(text, 1, maxLen - 3) .. "..."
end

local function basename(path)
    return path:match("[^/]+$") or path
end

local function center(y, text, textColor)
    term.setCursorPos(math.floor((w - #text) / 2) + 1, y)
    term.setTextColor(textColor or colors.white)
    term.write(text)
end

-- =====================
--   Drawing functions
-- =====================

local function writeLine(content, x, y)
    term.setCursorPos(x, y)
    term.clearLine()
    if type(content) == "table" then
        for _, value in ipairs(content) do
            if type(value) == "number" then
                term.setTextColor(value)
            else
                term.write(tostring(value))
            end
        end
    else
        term.write(tostring(content))
    end
end

local function drawProgressLine(text, textColor, percentage, y)
    local percentText = string.format("%3d%%", percentage)
    local barText = makeBar(percentage, 15)

    -- length of " " + percentText + " [" + barText + "]"
    local reserved = 1 + #percentText + 2 + #barText + 1

    local maxTextLen = math.max(1, w - reserved - 1)
    text = truncate(text, maxTextLen)

    local content = {
        textColor or colors.white,
        text,
        colors.white,
        string.rep(" ", maxTextLen - #text + 1),
        percentText,
        colors.lightGray,
        " [",
        colors.green,
        barText,
        colors.lightGray,
        "]"
    }

    writeLine(content, 1, y)
end

local function drawFileLine(index, filename, percent)
    local y = index + 2
    
    drawProgressLine(filename, colors.cyan, percent, y)
end

local function drawTotalProgress(done, total)
    local percent = math.floor((done / total) * 100)
    local text = string.format("Downloaded %d/%d files ", done, total)

    drawProgressLine(text, colors.cyan, percent, h)
end

local function status(text, color)
    local content = {
        color or colors.white,
        text
    }

    writeLine(content, 1, h - 1)
end

local function download(url, backup, dest)
    local response = http.get(url)

    if not response and backup then
        status("Failed main download. Trying backup...", colors.orange)
        response = http.get(backup)
    end

    if not response then
        return false, "Failed to download " .. dest
    end

    local content = response.readAll()
    response.close()

    local dir = fs.getDir(dest)
    if dir ~= "" then
        fs.makeDir(dir)
    end

    local file = fs.open(dest, "w")
    file.write(content)
    file.close()

    return true
end

term.clear()
term.setCursorPos(1, 1)

if not http then
    error("HTTP is not enabled. This is required for this programm to work!", 0)
end

center(1, "Installing files...", colors.lightGray)

local total = #files
local completed = 0

drawTotalProgress(completed, total)

for i, file in ipairs(files) do
    local name = basename(file.path)

    status("Installing " .. name .. "...", colors.lightGray)

    local ok, err = download(
        file.url,
        file.backup,
        file.path
    )

    if not ok then
        term.setCursorPos(1, i + 1)
        term.clearLine()
        error(err, 0)
    end

    for p = 0, 90, 5 do
        drawFileLine(i, name, p)
        sleep(0.05)
    end

    drawFileLine(i, name, 100)

    completed = completed + 1
    drawTotalProgress(completed, total)

    status("Installed " .. file.path, colors.green)

    sleep(0.5)
end

writeLine({colors.green, "Download complete! ", colors.lightGray, "Rebooting in 3 seconds..."}, 1, h)

sleep(1)
writeLine({colors.green, "Download complete! ", colors.lightGray, "Rebooting in 2 seconds..."}, 1, h)

sleep(1)
writeLine({colors.green, "Download complete! ", colors.lightGray, "Rebooting in 1 second..."}, 1, h)

sleep(1)
os.reboot()