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

#include "bus-polkit.h"
#include "bus-util.h"
#include "dbus-util.h"
#include "escape.h"
#include "parse-util.h"
#include "path-util.h"
#include "unit-printf.h"
#include "user-util.h"
#include "unit.h"

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

        Unit *u = userdata, *trigger;

        assert(bus);
        assert(reply);
        assert(u);

        trigger = UNIT_TRIGGER(u);

        return sd_bus_message_append(reply, "s", trigger ? trigger->id : NULL);
}

BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);

static inline bool valid_user_group_name_or_id_relaxed(const char *u) {
        return valid_user_group_name(u, VALID_USER_ALLOW_NUMERIC|VALID_USER_RELAX);
}

BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed, valid_user_group_name_or_id_relaxed);
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);

int bus_set_transient_string(
                Unit *u,
                const char *name,
                char **p,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        const char *v;
        int r;

        assert(p);

        r = sd_bus_message_read(message, "s", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                r = free_and_strdup(p, empty_to_null(v));
                if (r < 0)
                        return r;

                unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
                                    "%s=%s", name, strempty(v));
        }

        return 1;
}

int bus_set_transient_bool(
                Unit *u,
                const char *name,
                bool *p,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        int v, r;

        assert(p);

        r = sd_bus_message_read(message, "b", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                *p = v;
                unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
        }

        return 1;
}

int bus_set_transient_usec_internal(
                Unit *u,
                const char *name,
                usec_t *p,
                bool fix_0,
                sd_bus_message *message,
                UnitWriteFlags flags,
                sd_bus_error *error) {

        uint64_t v;
        int r;

        assert(p);

        r = sd_bus_message_read(message, "t", &v);
        if (r < 0)
                return r;

        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                if (fix_0)
                        *p = v != 0 ? v: USEC_INFINITY;
                else
                        *p = v;

                char *n = strndupa_safe(name, strlen(name) - 4);
                unit_write_settingf(u, flags, name, "%sSec=%s", n, FORMAT_TIMESPAN(v, USEC_PER_MSEC));
        }

        return 1;
}

int bus_verify_manage_units_async_full(
                Unit *u,
                const char *verb,
                int capability,
                const char *polkit_message,
                bool interactive,
                sd_bus_message *call,
                sd_bus_error *error) {

        const char *details[9] = {
                "unit", u->id,
                "verb", verb,
        };

        if (polkit_message) {
                details[4] = "polkit.message";
                details[5] = polkit_message;
                details[6] = "polkit.gettext_domain";
                details[7] = GETTEXT_PACKAGE;
        }

        return bus_verify_polkit_async(
                        call,
                        capability,
                        "org.freedesktop.systemd1.manage-units",
                        details,
                        interactive,
                        UID_INVALID,
                        &u->manager->polkit_registry,
                        error);
}

/* ret_format_str is an accumulator, so if it has any pre-existing content, new options will be appended to it */
int bus_read_mount_options(
                sd_bus_message *message,
                sd_bus_error *error,
                MountOptions **ret_options,
                char **ret_format_str,
                const char *separator) {

        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
        _cleanup_free_ char *format_str = NULL;
        const char *mount_options, *partition;
        int r;

        assert(message);
        assert(ret_options);
        assert(separator);

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

        while ((r = sd_bus_message_read(message, "(ss)", &partition, &mount_options)) > 0) {
                _cleanup_free_ char *escaped = NULL;
                _cleanup_free_ MountOptions *o = NULL;
                PartitionDesignator partition_designator;

                if (chars_intersect(mount_options, WHITESPACE))
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
                                                "Invalid mount options string, contains whitespace character(s): %s", mount_options);

                partition_designator = partition_designator_from_string(partition);
                if (partition_designator < 0)
                        return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid partition name %s", partition);

                /* Need to store the options with the escapes, so that they can be parsed again */
                escaped = shell_escape(mount_options, ":");
                if (!escaped)
                        return -ENOMEM;

                if (!strextend_with_separator(&format_str, separator, partition, ":", escaped))
                        return -ENOMEM;

                o = new(MountOptions, 1);
                if (!o)
                        return -ENOMEM;
                *o = (MountOptions) {
                        .partition_designator = partition_designator,
                        .options = strdup(mount_options),
                };
                if (!o->options)
                        return -ENOMEM;
                LIST_APPEND(mount_options, options, TAKE_PTR(o));
        }
        if (r < 0)
                return r;

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

        if (options) {
                if (ret_format_str) {
                        char *final = strjoin(*ret_format_str, !isempty(*ret_format_str) ? separator : "", format_str);
                        if (!final)
                                return -ENOMEM;
                        free_and_replace(*ret_format_str, final);
                }
                LIST_JOIN(mount_options, *ret_options, options);
        }

        return 0;
}

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

        ActivationDetails **details = ASSERT_PTR(userdata);
        _cleanup_strv_free_ char **pairs = NULL;
        int r;

        assert(reply);

        r = activation_details_append_pair(*details, &pairs);
        if (r < 0)
                return r;

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

        STRV_FOREACH_PAIR(key, value, pairs) {
                r = sd_bus_message_append(reply, "(ss)", *key, *value);
                if (r < 0)
                        return r;
        }

        return sd_bus_message_close_container(reply);
}
