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

#include <unistd.h>

#include "sd-login.h"

#include "bus-map-properties.h"
#include "hostname-util.h"
#include "locale-util.h"
#include "memory-util.h"
#include "sort-util.h"
#include "systemctl-list-machines.h"
#include "systemctl-util.h"
#include "systemctl.h"
#include "terminal-util.h"

const struct bus_properties_map machine_info_property_map[] = {
        /* Might good to keep same order here as in bus_manager_vtable[], server side */
        { "Version",            "s", NULL, offsetof(struct machine_info, version)        },
        { "Tainted",            "s", NULL, offsetof(struct machine_info, tainted)        },
        { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp)      },
        { "NNames",             "u", NULL, offsetof(struct machine_info, n_names)        },
        { "NFailedUnits",       "u", NULL, offsetof(struct machine_info, n_failed_units) },
        { "NJobs",              "u", NULL, offsetof(struct machine_info, n_jobs)         },
        { "ControlGroup",       "s", NULL, offsetof(struct machine_info, control_group)  },
        { "SystemState",        "s", NULL, offsetof(struct machine_info, state)          },
        {}
};

void machine_info_clear(struct machine_info *info) {
        assert(info);

        free(info->name);
        free(info->version);
        free(info->tainted);
        free(info->control_group);
        free(info->state);
        zero(*info);
}

static void free_machines_list(struct machine_info *machine_infos, int n) {
        if (!machine_infos)
                return;

        for (int i = 0; i < n; i++)
                machine_info_clear(&machine_infos[i]);

        free(machine_infos);
}

static int compare_machine_info(const struct machine_info *a, const struct machine_info *b) {
        int r;

        r = CMP(b->is_host, a->is_host);
        if (r != 0)
                return r;

        return strcasecmp(a->name, b->name);
}

static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *container = NULL;
        int r;

        assert(mi);

        if (!bus) {
                r = sd_bus_open_system_machine(&container, mi->name);
                if (r < 0)
                        return r;

                bus = container;
        }

        r = bus_map_all_properties(
                        bus,
                        "org.freedesktop.systemd1",
                        "/org/freedesktop/systemd1",
                        machine_info_property_map,
                        BUS_MAP_STRDUP,
                        NULL,
                        NULL,
                        mi);
        if (r < 0)
                return r;

        return 0;
}

static bool output_show_machine(const char *name, char **patterns) {
        return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
}

static int get_machine_list(
                sd_bus *bus,
                struct machine_info **_machine_infos,
                char **patterns) {

        struct machine_info *machine_infos = NULL;
        _cleanup_strv_free_ char **m = NULL;
        _cleanup_free_ char *hn = NULL;
        int c = 0, r;

        hn = gethostname_malloc();
        if (!hn)
                return log_oom();

        if (output_show_machine(hn, patterns)) {
                if (!GREEDY_REALLOC0(machine_infos, c+1))
                        return log_oom();

                machine_infos[c].is_host = true;
                machine_infos[c].name = TAKE_PTR(hn);

                (void) get_machine_properties(bus, &machine_infos[c]);
                c++;
        }

        r = sd_get_machine_names(&m);
        if (r < 0)
                return log_error_errno(r, "Failed to get machine list: %m");

        STRV_FOREACH(i, m) {
                _cleanup_free_ char *class = NULL;

                if (!output_show_machine(*i, patterns))
                        continue;

                sd_machine_get_class(*i, &class);
                if (!streq_ptr(class, "container"))
                        continue;

                if (!GREEDY_REALLOC0(machine_infos, c+1)) {
                        free_machines_list(machine_infos, c);
                        return log_oom();
                }

                machine_infos[c].is_host = false;
                machine_infos[c].name = strdup(*i);
                if (!machine_infos[c].name) {
                        free_machines_list(machine_infos, c);
                        return log_oom();
                }

                (void) get_machine_properties(NULL, &machine_infos[c]);
                c++;
        }

        *_machine_infos = machine_infos;
        return c;
}

static int output_machines_list(struct machine_info *machine_infos, unsigned n) {
        _cleanup_(table_unrefp) Table *table = NULL;
        bool state_missing = false;
        int r;

        assert(machine_infos || n == 0);

        table = table_new("", "name", "state", "failed", "jobs");
        if (!table)
                return log_oom();

        table_set_header(table, arg_legend != 0);
        if (arg_plain) {
                /* Hide the 'glyph' column when --plain is requested */
                r = table_hide_column_from_display(table, 0);
                if (r < 0)
                        return log_error_errno(r, "Failed to hide column: %m");
        }
        if (arg_full)
                table_set_width(table, 0);

        table_set_ersatz_string(table, TABLE_ERSATZ_DASH);

        for (struct machine_info *m = machine_infos; m < machine_infos + n; m++) {
                _cleanup_free_ char *mname = NULL;
                const char *on_state = "", *on_failed = "";
                bool circle = false;

                if (streq_ptr(m->state, "degraded")) {
                        on_state = ansi_highlight_red();
                        circle = true;
                } else if (!streq_ptr(m->state, "running")) {
                        on_state = ansi_highlight_yellow();
                        circle = true;
                }

                if (m->n_failed_units > 0)
                        on_failed = ansi_highlight_red();
                else
                        on_failed =  "";

                if (!m->state)
                        state_missing = true;

                if (m->is_host)
                        mname = strjoin(strna(m->name), " (host)");

                r = table_add_many(table,
                                   TABLE_STRING, circle ? special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE) : " ",
                                   TABLE_SET_COLOR, on_state,
                                   TABLE_STRING, m->is_host ? mname : strna(m->name),
                                   TABLE_STRING, strna(m->state),
                                   TABLE_SET_COLOR, on_state,
                                   TABLE_UINT32, m->n_failed_units,
                                   TABLE_SET_COLOR, on_failed,
                                   TABLE_UINT32, m->n_jobs);
                if (r < 0)
                        return table_log_add_error(r);
        }

        r = output_table(table);
        if (r < 0)
                return r;

        if (arg_legend != 0) {
                printf("\n");
                if (state_missing && geteuid() != 0)
                        printf("Notice: some information only available to privileged users was not shown.\n");
                printf("%u machines listed.\n", n);
        }

        return 0;
}

int verb_list_machines(int argc, char *argv[], void *userdata) {
        struct machine_info *machine_infos = NULL;
        sd_bus *bus;
        int r, rc;

        r = acquire_bus(BUS_MANAGER, &bus);
        if (r < 0)
                return r;

        r = get_machine_list(bus, &machine_infos, strv_skip(argv, 1));
        if (r < 0)
                return r;

        pager_open(arg_pager_flags);

        typesafe_qsort(machine_infos, r, compare_machine_info);
        rc = output_machines_list(machine_infos, r);
        free_machines_list(machine_infos, r);

        return rc;
}
