local basalt = require("/lib/basalt")
local main = basalt.getMainFrame()

local latest_apps_json = {}

function http_get(url)
  local req = http.get(url)
  local resp = req.readAll()
  req.close()
  return resp
end

local app_views = {}

local y = 1

function add_app(name, colour, url, file, installed, upgradeable, app_remote_version, app_remote_path)

  local frame = main:addFrame()
    :setBackground(colours.lightGrey)
    :setSize(26, 3)
    :setPosition(1, y)

  frame:addFrame()
    :setPosition(1, 1)
    :setSize(1, 3)
    :setBackground(colours[colour])

  frame:addLabel()
    :setPosition(3, 2)
    :setText(name)

  local install_btn = frame:addButton()
    :setPosition(15, 2)
    :setSize(10, 1)
    :setBackground(colours.grey)
    :setForeground(colours.black)

    :onClick(function(install_btn)
      local current_manifest = {}
      local manifest_file_content = ""
      local mf_handle = fs.open("/app_manifest.json", "r")
      if mf_handle then
        manifest_file_content = mf_handle.readAll()
        mf_handle.close()
      end

      if manifest_file_content ~= "" then

        local unserialised_data = textutils.unserialiseJSON(manifest_file_content)
        if type(unserialised_data) == "table" then
          current_manifest = unserialised_data
        else

        end
      else

      end

      if installed then
        if upgradeable then

          local app_content = http_get(url) 
          local app_file_handle = fs.open(file, "w")
          if app_file_handle then
            app_file_handle.write(app_content)
            app_file_handle.close()

            current_manifest[name] = { version = app_remote_version, path = app_remote_path }

          else

          end
        else

          local delete_success = fs.delete(file)
          if delete_success then

            current_manifest[name] = nil

          else

            current_manifest[name] = nil

          end
        end
      else

        local app_content = http_get(url) 
        local app_file_handle = fs.open(file, "w")
        if app_file_handle then
          app_file_handle.write(app_content)
          app_file_handle.close()

          current_manifest[name] = { version = app_remote_version, path = app_remote_path }

        else

        end
      end

      local serialized_manifest_to_write = textutils.serialiseJSON(current_manifest) 

      local mf_handle_write = fs.open("/app_manifest.json", "w")
      if mf_handle_write then
        mf_handle_write.write(serialized_manifest_to_write)
        mf_handle_write.close()

      else

      end

      refresh()

    end)
  table.insert(app_views, frame) 

  if installed then
    install_btn:setText("Remove")
    install_btn:setBackground(colours.red)
  else
    install_btn:setText("Install")
  end

  if upgradeable then
    install_btn:setText("Update")
    install_btn:setBackground(colours.yellow)
  end

  y = y + 4 
end

function refresh()

  local apps_json_content = http_get("https://git.mcorangehq.xyz/xomf/slabOS/raw/branch/main/apps.json")
  local unserialise_apps_success, unserialised_apps_json = pcall(textutils.unserialiseJSON, apps_json_content)

  if not unserialise_apps_success or type(unserialised_apps_json) ~= "table" then

    return 
  end
  latest_apps_json = unserialised_apps_json 

  local local_manifest = {}
  local manifest_file_content = ""
  local mf_handle = fs.open("/app_manifest.json", "r")
  if mf_handle then
    manifest_file_content = mf_handle.readAll()
    mf_handle.close()

  else

  end

  if manifest_file_content ~= "" then
    local unserialised_data = textutils.unserialiseJSON(manifest_file_content)
    if type(unserialised_data) == "table" then
      local_manifest = unserialised_data

    else

    end
  end

  for _, view_frame in pairs(app_views) do
    view_frame:destroy()
  end
  app_views = {} 
  y = 1 

  for app_name, app_data in pairs(latest_apps_json) do
    local installed = false
    local upgradeable = false

    if local_manifest[app_name] then
      installed = true

      if app_data.version ~= local_manifest[app_name].version then
        upgradeable = true

      else

      end
    else

    end

    add_app(app_name, app_data.colour, app_data.url, app_data.path, installed, upgradeable, app_data.version, app_data.path)
  end

end

refresh()


basalt.run()