namespace QuickSetup {
    public void queue_sam_task(string package_id, string app_name, string manager_id, string task) {
        queue_sam_task_with_tags(package_id, app_name, manager_id, task, {});
    }

    public void queue_sam_task_with_tags(string package_id, string app_name, string manager_id, string task, string[] tags) {
        try {
            var proxy = new DBusProxy.for_bus_sync(
                BusType.SYSTEM,
                DBusProxyFlags.NONE,
                null,
                "io.stillhq.SamService",      // service name
                "/io/stillhq/SamService",     // object path
                "io.stillhq.SamService"       // interface
            );

            var vardict = new VariantDict();
            vardict.insert("package_id", "s", package_id);
            vardict.insert("app_name", "s", app_name);
            vardict.insert("manager_id", "s", manager_id);
            vardict.insert("task", "s", task);
            vardict.insert_value("tags", new Variant.strv(tags));

            var vardict_variant = vardict.end();

            proxy.call_sync("add_dict_to_queue", new Variant.tuple({vardict_variant}), DBusCallFlags.NONE, -1, null);
            print("Added %s to queue", app_name);
        } catch (Error e) {
            error("Failed to connect to SAM: %s", e.message);
        }
    }

    public void install_app(AppData app, string task = "INSTALL") {
        queue_sam_task(app.app_id, app.name, app.package_manager, task);
        if (task == "INSTALL") {
            pin_app(app);
        }
    }

    public void queue_system_update() {
        // Keep system updates ahead of app installs in the SAM queue.
        queue_sam_task_with_tags("system-update", "System Update", "system", "UPDATE", {"system"});
    }
}
