/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "bus-get-properties.h"
#include "dbus-path.h"
#include "dbus-util.h"
#include "list.h"
#include "path.h"
#include "path-util.h"
#include "string-util.h"
#include "unit.h"

static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, path_result, PathResult);

static int property_get_paths(
                sd_bus *bus,
                const char *path,
                const char *interface,
                const char *property,
                sd_bus_message *reply,
                void *userdata,
                sd_bus_error *error) {

        Path *p = userdata;
        PathSpec *k;
        int r;

        assert(bus);
        assert(reply);
        assert(p);

        r = sd_bus_message_open_container(reply, 'a', "(ss)");
        if (r < 0)
                return r;

        LIST_FOREACH(spec, k, p->specs) {
                r = sd_bus_message_append(reply, "(ss)", path_type_to_string(k->type), k->path);
                if (r < 0)
                        return r;
        }

        return sd_bus_message_close_container(reply);
}

const sd_bus_vtable bus_path_vtable[] = {
        SD_BUS_VTABLE_START(0),
        SD_BUS_PROPERTY("Unit", "s", bus_property_get_triggered_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
        SD_BUS_PROPERTY("Paths", "a(ss)", property_get_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
        SD_BUS_PROPERTY("MakeDirectory", "b", bus_property_get_bool, offsetof(Path, make_directory), SD_BUS_VTABLE_PROPERTY_CONST),
        SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Path, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
        SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Path, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
        SD_BUS_VTABLE_END
};

static int bus_path_set_transient_property(
                Path *p,
                const char *name,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        Unit *u = UNIT(p);
        int r;

        assert(p);
        assert(name);
        assert(message);

        flags |= UNIT_PRIVATE;

        if (streq(name, "MakeDirectory"))
                return bus_set_transient_bool(u, name, &p->make_directory, message, flags, error);

        if (streq(name, "DirectoryMode"))
                return bus_set_transient_mode_t(u, name, &p->directory_mode, message, flags, error);

        if (streq(name, "Paths")) {
                const char *type_name, *path;
                bool empty = true;

                r = sd_bus_message_enter_container(message, 'a', "(ss)");
                if (r < 0)
                        return r;

                while ((r = sd_bus_message_read(message, "(ss)", &type_name, &path)) > 0) {
                        PathType t;

                        t = path_type_from_string(type_name);
                        if (t < 0)
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type: %s", type_name);

                        if (isempty(path))
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is empty", type_name);

                        if (!path_is_absolute(path))
                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is not absolute: %s", type_name, path);

                        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                                _cleanup_free_ char *k = NULL;
                                PathSpec *s;

                                k = strdup(path);
                                if (!k)
                                        return -ENOMEM;

                                path_simplify(k);

                                s = new0(PathSpec, 1);
                                if (!s)
                                        return -ENOMEM;

                                s->unit = u;
                                s->path = TAKE_PTR(k);
                                s->type = t;
                                s->inotify_fd = -1;

                                LIST_PREPEND(spec, p->specs, s);

                                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", type_name, path);
                        }

                        empty = false;
                }
                if (r < 0)
                        return r;

                r = sd_bus_message_exit_container(message);
                if (r < 0)
                        return r;

                if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
                        path_free_specs(p);
                        unit_write_settingf(u, flags, name, "PathExists=");
                }

                return 1;
        }

        return 0;
}

int bus_path_set_property(
                Unit *u,
                const char *name,
                sd_bus_message *message,
                UnitWriteFlags mode,
                sd_bus_error *error) {

        Path *p = PATH(u);

        assert(p);
        assert(name);
        assert(message);

        if (u->transient && u->load_state == UNIT_STUB)
                return bus_path_set_transient_property(p, name, message, mode, error);

        return 0;
}
