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

#include "cgroup-util.h"
#include "errno-util.h"
#include "journald-client.h"
#include "nulstr-util.h"
#include "pcre2-util.h"

/* This consumes both `allow_list` and `deny_list` arguments. Hence, those arguments are not owned by the
 * caller anymore and should not be freed. */
static void client_set_filtering_patterns(ClientContext *c, Set *allow_list, Set *deny_list) {
        assert(c);

        set_free_and_replace(c->log_filter_allowed_patterns, allow_list);
        set_free_and_replace(c->log_filter_denied_patterns, deny_list);
}

static int client_parse_log_filter_nulstr(const char *nulstr, size_t len, Set **ret) {
        _cleanup_set_free_ Set *s = NULL;
        _cleanup_strv_free_ char **patterns_strv = NULL;
        int r;

        assert(nulstr);
        assert(ret);

        patterns_strv = strv_parse_nulstr(nulstr, len);
        if (!patterns_strv)
                return log_oom_debug();

        STRV_FOREACH(pattern, patterns_strv) {
                _cleanup_(pattern_freep) pcre2_code *compiled_pattern = NULL;

                r = pattern_compile_and_log(*pattern, 0, &compiled_pattern);
                if (r < 0)
                        return r;

                r = set_ensure_consume(&s, &pcre2_code_hash_ops_free, TAKE_PTR(compiled_pattern));
                if (r < 0)
                        return log_debug_errno(r, "Failed to insert regex into set: %m");
        }

        *ret = TAKE_PTR(s);

        return 0;
}

int client_context_read_log_filter_patterns(ClientContext *c, const char *cgroup) {
        char *deny_list_xattr, *xattr_end;
        _cleanup_free_ char *xattr = NULL, *unit_cgroup = NULL;
        _cleanup_set_free_ Set *allow_list = NULL, *deny_list = NULL;
        int r;

        assert(c);

        r = cg_path_get_unit_path(cgroup, &unit_cgroup);
        if (r < 0)
                return log_debug_errno(r, "Failed to get the unit's cgroup path for %s: %m", cgroup);

        r = cg_get_xattr_malloc(SYSTEMD_CGROUP_CONTROLLER, unit_cgroup, "user.journald_log_filter_patterns", &xattr);
        if (r < 0) {
                if (!ERRNO_IS_XATTR_ABSENT(r))
                        return log_debug_errno(r, "Failed to get user.journald_log_filter_patterns xattr for %s: %m", unit_cgroup);

                client_set_filtering_patterns(c, NULL, NULL);
                return 0;
        }

        xattr_end = xattr + r;

        /* We expect '0xff' to be present in the attribute, even if the lists are empty. We expect the
         * following:
         * - Allow list, but no deny list: 0xXX, ...., 0xff
         * - No allow list, but deny list: 0xff, 0xXX, ....
         * - Allow list, and deny list:    0xXX, ...., 0xff, 0xXX, ....
         * This is due to the fact allowed and denied patterns list are two nulstr joined together with '0xff'.
         * None of the allowed or denied nulstr have a nul-termination character.
         *
         * We do not expect both the allow list and deny list to be empty, as this condition is tested
         * before writing to xattr. */
        deny_list_xattr = memchr(xattr, (char)0xff, r);
        if (!deny_list_xattr)
                return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "Missing delimiter in cgroup user.journald_log_filter_patterns attribute: %m");

        r = client_parse_log_filter_nulstr(xattr, deny_list_xattr - xattr, &allow_list);
        if (r < 0)
                return r;

        /* Use 'deny_list_xattr + 1' to skip '0xff'. */
        ++deny_list_xattr;
        r = client_parse_log_filter_nulstr(deny_list_xattr, xattr_end - deny_list_xattr, &deny_list);
        if (r < 0)
                return r;

        client_set_filtering_patterns(c, TAKE_PTR(allow_list), TAKE_PTR(deny_list));

        return 0;
}

int client_context_check_keep_log(ClientContext *c, const char *message, size_t len) {
        pcre2_code *regex;

        if (!c || !message)
                return true;

        SET_FOREACH(regex, c->log_filter_denied_patterns)
                if (pattern_matches_and_log(regex, message, len, NULL) > 0)
                        return false;

        SET_FOREACH(regex, c->log_filter_allowed_patterns)
                if (pattern_matches_and_log(regex, message, len, NULL) > 0)
                        return true;

        return set_isempty(c->log_filter_allowed_patterns);
}
