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

#include "analyze.h"
#include "analyze-dot.h"
#include "bus-error.h"
#include "bus-locator.h"
#include "bus-unit-util.h"
#include "glob-util.h"
#include "terminal-util.h"

static int graph_one_property(
                sd_bus *bus,
                const UnitInfo *u,
                const char *prop,
                const char *color,
                char *patterns[],
                char *from_patterns[],
                char *to_patterns[]) {

        _cleanup_strv_free_ char **units = NULL;
        bool match_patterns;
        int r;

        assert(u);
        assert(prop);
        assert(color);

        match_patterns = strv_fnmatch(patterns, u->id);

        if (!strv_isempty(from_patterns) && !match_patterns && !strv_fnmatch(from_patterns, u->id))
                return 0;

        r = bus_get_unit_property_strv(bus, u->unit_path, prop, &units);
        if (r < 0)
                return r;

        STRV_FOREACH(unit, units) {
                bool match_patterns2;

                match_patterns2 = strv_fnmatch(patterns, *unit);

                if (!strv_isempty(to_patterns) && !match_patterns2 && !strv_fnmatch(to_patterns, *unit))
                        continue;

                if (!strv_isempty(patterns) && !match_patterns && !match_patterns2)
                        continue;

                printf("\t\"%s\"->\"%s\" [color=\"%s\"];\n", u->id, *unit, color);
        }

        return 0;
}

static int graph_one(sd_bus *bus, const UnitInfo *u, char *patterns[], char *from_patterns[], char *to_patterns[]) {
        int r;

        assert(bus);
        assert(u);

        if (IN_SET(arg_dot, DEP_ORDER, DEP_ALL)) {
                r = graph_one_property(bus, u, "After", "green", patterns, from_patterns, to_patterns);
                if (r < 0)
                        return r;
        }

        if (IN_SET(arg_dot, DEP_REQUIRE, DEP_ALL)) {
                r = graph_one_property(bus, u, "Requires", "black", patterns, from_patterns, to_patterns);
                if (r < 0)
                        return r;
                r = graph_one_property(bus, u, "Requisite", "darkblue", patterns, from_patterns, to_patterns);
                if (r < 0)
                        return r;
                r = graph_one_property(bus, u, "Wants", "grey66", patterns, from_patterns, to_patterns);
                if (r < 0)
                        return r;
                r = graph_one_property(bus, u, "Conflicts", "red", patterns, from_patterns, to_patterns);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int expand_patterns(sd_bus *bus, char **patterns, char ***ret) {
        _cleanup_strv_free_ char **expanded_patterns = NULL;
        int r;

        STRV_FOREACH(pattern, patterns) {
                _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
                _cleanup_free_ char *unit = NULL, *unit_id = NULL;

                if (strv_extend(&expanded_patterns, *pattern) < 0)
                        return log_oom();

                if (string_is_glob(*pattern))
                        continue;

                unit = unit_dbus_path_from_name(*pattern);
                if (!unit)
                        return log_oom();

                r = sd_bus_get_property_string(
                                bus,
                                "org.freedesktop.systemd1",
                                unit,
                                "org.freedesktop.systemd1.Unit",
                                "Id",
                                &error,
                                &unit_id);
                if (r < 0)
                        return log_error_errno(r, "Failed to get ID: %s", bus_error_message(&error, r));

                if (!streq(*pattern, unit_id)) {
                        if (strv_extend(&expanded_patterns, unit_id) < 0)
                                return log_oom();
                }
        }

        *ret = TAKE_PTR(expanded_patterns); /* do not free */

        return 0;
}

int verb_dot(int argc, char *argv[], void *userdata) {
        _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        _cleanup_strv_free_ char **expanded_patterns = NULL;
        _cleanup_strv_free_ char **expanded_from_patterns = NULL;
        _cleanup_strv_free_ char **expanded_to_patterns = NULL;
        int r;
        UnitInfo u;

        r = acquire_bus(&bus, NULL);
        if (r < 0)
                return bus_log_connect_error(r, arg_transport);

        r = expand_patterns(bus, strv_skip(argv, 1), &expanded_patterns);
        if (r < 0)
                return r;

        r = expand_patterns(bus, arg_dot_from_patterns, &expanded_from_patterns);
        if (r < 0)
                return r;

        r = expand_patterns(bus, arg_dot_to_patterns, &expanded_to_patterns);
        if (r < 0)
                return r;

        r = bus_call_method(bus, bus_systemd_mgr, "ListUnits", &error, &reply, NULL);
        if (r < 0)
                return log_error_errno(r, "Failed to list units: %s", bus_error_message(&error, r));

        r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
        if (r < 0)
                return bus_log_parse_error(r);

        printf("digraph systemd {\n");

        while ((r = bus_parse_unit_info(reply, &u)) > 0) {

                r = graph_one(bus, &u, expanded_patterns, expanded_from_patterns, expanded_to_patterns);
                if (r < 0)
                        return r;
        }
        if (r < 0)
                return bus_log_parse_error(r);

        printf("}\n");

        log_info("   Color legend: black     = Requires\n"
                 "                 dark blue = Requisite\n"
                 "                 dark grey = Wants\n"
                 "                 red       = Conflicts\n"
                 "                 green     = After\n");

        if (on_tty() && !arg_quiet)
                log_notice("-- You probably want to process this output with graphviz' dot tool.\n"
                           "-- Try a shell pipeline like 'systemd-analyze dot | dot -Tsvg > systemd.svg'!\n");

        return 0;
}
