/*
 * libqos driver framework
 *
 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>
 */

#include "qemu/osdep.h"
#include "libqtest.h"
#include "qemu/queue.h"
#include "libqos/qgraph_internal.h"
#include "libqos/qgraph.h"

#define QGRAPH_PRINT_DEBUG 0
#define QOS_ROOT ""
typedef struct QOSStackElement QOSStackElement;

/* Graph Edge.*/
struct QOSGraphEdge {
    QOSEdgeType type;
    char *dest;
    void *arg;                /* just for QEDGE_CONTAINS
                               * and QEDGE_CONSUMED_BY */
    char *extra_device_opts;  /* added to -device option, "," is
                               * automatically added
                               */
    char *before_cmd_line;    /* added before node cmd_line */
    char *after_cmd_line;     /* added after -device options */
    char *edge_name;          /* used by QEDGE_CONTAINS */
    QSLIST_ENTRY(QOSGraphEdge) edge_list;
};

typedef QSLIST_HEAD(, QOSGraphEdge) QOSGraphEdgeList;

/**
 * Stack used to keep track of the discovered path when using
 * the DFS algorithm
 */
struct QOSStackElement {
    QOSGraphNode *node;
    QOSStackElement *parent;
    QOSGraphEdge *parent_edge;
    int length;
};

/* Each enty in these hash table will consist of <string, node/edge> pair. */
static GHashTable *edge_table;
static GHashTable *node_table;

/* stack used by the DFS algorithm to store the path from machine to test */
static QOSStackElement qos_node_stack[QOS_PATH_MAX_ELEMENT_SIZE];
static int qos_node_tos;

/**
 * add_edge(): creates an edge of type @type
 * from @source to @dest node, and inserts it in the
 * edges hash table
 *
 * Nodes @source and @dest do not necessarily need to exist.
 * Possibility to add also options (see #QOSGraphEdgeOptions)
 * edge->edge_name is used as identifier for get_device relationships,
 * so by default is equal to @dest.
 */
static void add_edge(const char *source, const char *dest,
                     QOSEdgeType type, QOSGraphEdgeOptions *opts)
{
    char *key;
    QOSGraphEdgeList *list = g_hash_table_lookup(edge_table, source);
    QOSGraphEdgeOptions def_opts = { };

    if (!list) {
        list = g_new0(QOSGraphEdgeList, 1);
        key = g_strdup(source);
        g_hash_table_insert(edge_table, key, list);
    }

    if (!opts) {
        opts = &def_opts;
    }

    QOSGraphEdge *edge = g_new0(QOSGraphEdge, 1);
    edge->type = type;
    edge->dest = g_strdup(dest);
    edge->edge_name = g_strdup(opts->edge_name ?: dest);
    edge->arg = g_memdup(opts->arg, opts->size_arg);

    edge->before_cmd_line =
        opts->before_cmd_line ? g_strconcat(" ", opts->before_cmd_line, NULL) : NULL;
    edge->extra_device_opts =
        opts->extra_device_opts ? g_strconcat(",", opts->extra_device_opts, NULL) : NULL;
    edge->after_cmd_line =
        opts->after_cmd_line ? g_strconcat(" ", opts->after_cmd_line, NULL) : NULL;

    QSLIST_INSERT_HEAD(list, edge, edge_list);
}

/* destroy_edges(): frees all edges inside a given @list */
static void destroy_edges(void *list)
{
    QOSGraphEdge *temp;
    QOSGraphEdgeList *elist = list;

    while (!QSLIST_EMPTY(elist)) {
        temp = QSLIST_FIRST(elist);
        QSLIST_REMOVE_HEAD(elist, edge_list);
        g_free(temp->dest);
        g_free(temp->before_cmd_line);
        g_free(temp->after_cmd_line);
        g_free(temp->extra_device_opts);
        g_free(temp->edge_name);
        g_free(temp->arg);
        g_free(temp);
    }
    g_free(elist);
}

/**
 * create_node(): creates a node @name of type @type
 * and inserts it to the nodes hash table.
 * By default, node is not available.
 */
static QOSGraphNode *create_node(const char *name, QOSNodeType type)
{
    if (g_hash_table_lookup(node_table, name)) {
        g_printerr("Node %s already created\n", name);
        abort();
    }

    QOSGraphNode *node = g_new0(QOSGraphNode, 1);
    node->type = type;
    node->available = false;
    node->name = g_strdup(name);
    g_hash_table_insert(node_table, node->name, node);
    return node;
}

/**
 * destroy_node(): frees a node @val from the nodes hash table.
 * Note that node->name is not free'd since it will represent the
 * hash table key
 */
static void destroy_node(void *val)
{
    QOSGraphNode *node = val;
    g_free(node->command_line);
    g_free(node);
}

/**
 * destroy_string(): frees @key from the nodes hash table.
 * Actually frees the node->name
 */
static void destroy_string(void *key)
{
    g_free(key);
}

/**
 * search_node(): search for a node @key in the nodes hash table
 * Returns the QOSGraphNode if found, #NULL otherwise
 */
static QOSGraphNode *search_node(const char *key)
{
    return g_hash_table_lookup(node_table, key);
}

/**
 * get_edgelist(): returns the edge list (value) assigned to
 * the @key in the edge hash table.
 * This list will contain all edges with source equal to @key
 *
 * Returns: on success: the %QOSGraphEdgeList
 *          otherwise: abort()
 */
static QOSGraphEdgeList *get_edgelist(const char *key)
{
    return g_hash_table_lookup(edge_table, key);
}

/**
 * search_list_edges(): search for an edge with destination @dest
 * in the given @edgelist.
 *
 * Returns: on success: the %QOSGraphEdge
 *          otherwise: #NULL
 */
static QOSGraphEdge *search_list_edges(QOSGraphEdgeList *edgelist,
                                       const char *dest)
{
    QOSGraphEdge *tmp, *next;
    if (!edgelist) {
        return NULL;
    }
    QSLIST_FOREACH_SAFE(tmp, edgelist, edge_list, next) {
        if (g_strcmp0(tmp->dest, dest) == 0) {
            break;
        }
    }
    return tmp;
}

/**
 * search_machine(): search for a machine @name in the node hash
 * table. A machine is the child of the root node.
 * This function forces the research in the childs of the root,
 * to check the node is a proper machine
 *
 * Returns: on success: the %QOSGraphNode
 *          otherwise: #NULL
 */
static QOSGraphNode *search_machine(const char *name)
{
    QOSGraphNode *n;
    QOSGraphEdgeList *root_list = get_edgelist(QOS_ROOT);
    QOSGraphEdge *e = search_list_edges(root_list, name);
    if (!e) {
        return NULL;
    }
    n = search_node(e->dest);
    if (n->type == QNODE_MACHINE) {
        return n;
    }
    return NULL;
}

/**
 * create_interface(): checks if there is already
 * a node @node in the node hash table, if not
 * creates a node @node of type #QNODE_INTERFACE
 * and inserts it. If there is one, check it's
 * a #QNODE_INTERFACE and abort() if it's not.
 */
static void create_interface(const char *node)
{
    QOSGraphNode *interface;
    interface = search_node(node);
    if (!interface) {
        create_node(node, QNODE_INTERFACE);
    } else if (interface->type != QNODE_INTERFACE) {
        fprintf(stderr, "Error: Node %s is not an interface\n", node);
        abort();
    }
}

/**
 * build_machine_cmd_line(): builds the command line for the machine
 * @node. The node name must be a valid qemu identifier, since it
 * will be used to build the command line.
 *
 * It is also possible to pass an optional @args that will be
 * concatenated to the command line.
 *
 * For machines, prepend -M to the machine name. ", @rgs" is added
 * after the -M <machine> command.
 */
static void build_machine_cmd_line(QOSGraphNode *node, const char *args)
{
    char *machine = qos_get_machine_type(node->name);
    if (args) {
        node->command_line = g_strconcat("-M ", machine, ",", args, NULL);
    } else {
        node->command_line = g_strconcat("-M ", machine, " ", NULL);
    }
}

/**
 * build_driver_cmd_line(): builds the command line for the driver
 * @node. The node name must be a valid qemu identifier, since it
 * will be used to build the command line.
 *
 * Driver do not need additional command line, since it will be
 * provided by the edge options.
 *
 * For drivers, prepend -device to the node name.
 */
static void build_driver_cmd_line(QOSGraphNode *node)
{
    node->command_line = g_strconcat(" -device ", node->name, NULL);
}

/* qos_print_cb(): callback prints all path found by the DFS algorithm. */
static void qos_print_cb(QOSGraphNode *path, int length)
{
    #if QGRAPH_PRINT_DEBUG
        printf("%d elements\n", length);

        if (!path) {
            return;
        }

        while (path->path_edge) {
            printf("%s ", path->name);
            switch (path->path_edge->type) {
            case QEDGE_PRODUCES:
                printf("--PRODUCES--> ");
                break;
            case QEDGE_CONSUMED_BY:
                printf("--CONSUMED_BY--> ");
                break;
            case QEDGE_CONTAINS:
                printf("--CONTAINS--> ");
                break;
            }
            path = search_node(path->path_edge->dest);
        }

        printf("%s\n\n", path->name);
    #endif
}

/* qos_push(): push a node @el and edge @e in the qos_node_stack */
static void qos_push(QOSGraphNode *el, QOSStackElement *parent,
                     QOSGraphEdge *e)
{
    int len = 0; /* root is not counted */
    if (qos_node_tos == QOS_PATH_MAX_ELEMENT_SIZE) {
        g_printerr("QOSStack: full stack, cannot push");
        abort();
    }

    if (parent) {
        len = parent->length + 1;
    }
    qos_node_stack[qos_node_tos++] = (QOSStackElement) {
        .node = el,
        .parent = parent,
        .parent_edge = e,
        .length = len,
    };
}

/* qos_tos(): returns the top of stack, without popping */
static QOSStackElement *qos_tos(void)
{
    return &qos_node_stack[qos_node_tos - 1];
}

/* qos_pop(): pops an element from the tos, setting it unvisited*/
static QOSStackElement *qos_pop(void)
{
    if (qos_node_tos == 0) {
        g_printerr("QOSStack: empty stack, cannot pop");
        abort();
    }
    QOSStackElement *e = qos_tos();
    e->node->visited = false;
    qos_node_tos--;
    return e;
}

/**
 * qos_reverse_path(): reverses the found path, going from
 * test-to-machine to machine-to-test
 */
static QOSGraphNode *qos_reverse_path(QOSStackElement *el)
{
    if (!el) {
        return NULL;
    }

    el->node->path_edge = NULL;

    while (el->parent) {
        el->parent->node->path_edge = el->parent_edge;
        el = el->parent;
    }

    return el->node;
}

/**
 * qos_traverse_graph(): graph-walking algorithm, using Depth First Search it
 * starts from the root @machine and walks all possible path until it
 * reaches a test node.
 * At that point, it reverses the path found and invokes the @callback.
 *
 * Being Depth First Search, time complexity is O(|V| + |E|), while
 * space is O(|V|). In this case, the maximum stack size is set by
 * QOS_PATH_MAX_ELEMENT_SIZE.
 */
static void qos_traverse_graph(QOSGraphNode *root, QOSTestCallback callback)
{
    QOSGraphNode *v, *dest_node, *path;
    QOSStackElement *s_el;
    QOSGraphEdge *e, *next;
    QOSGraphEdgeList *list;

    qos_push(root, NULL, NULL);

    while (qos_node_tos > 0) {
        s_el = qos_tos();
        v = s_el->node;
        if (v->visited) {
            qos_pop();
            continue;
        }
        v->visited = true;
        list = get_edgelist(v->name);
        if (!list) {
            qos_pop();
            if (v->type == QNODE_TEST) {
                v->visited = false;
                path = qos_reverse_path(s_el);
                callback(path, s_el->length);
            }
        } else {
            QSLIST_FOREACH_SAFE(e, list, edge_list, next) {
                dest_node = search_node(e->dest);

                if (!dest_node) {
                    fprintf(stderr, "node %s in %s -> %s does not exist\n",
                            e->dest, v->name, e->dest);
                    abort();
                }

                if (!dest_node->visited && dest_node->available) {
                    qos_push(dest_node, s_el, e);
                }
            }
        }
    }
}

/* QGRAPH API*/

QOSGraphNode *qos_graph_get_node(const char *key)
{
    return search_node(key);
}

bool qos_graph_has_node(const char *node)
{
    QOSGraphNode *n = search_node(node);
    return n != NULL;
}

QOSNodeType qos_graph_get_node_type(const char *node)
{
    QOSGraphNode *n = search_node(node);
    if (n) {
        return n->type;
    }
    return -1;
}

bool qos_graph_get_node_availability(const char *node)
{
    QOSGraphNode *n = search_node(node);
    if (n) {
        return n->available;
    }
    return false;
}

QOSGraphEdge *qos_graph_get_edge(const char *node, const char *dest)
{
    QOSGraphEdgeList *list = get_edgelist(node);
    return search_list_edges(list, dest);
}

QOSEdgeType qos_graph_edge_get_type(QOSGraphEdge *edge)
{
    if (!edge) {
        return -1;
    }
    return edge->type;;
}

char *qos_graph_edge_get_dest(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->dest;
}

void *qos_graph_edge_get_arg(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->arg;
}

char *qos_graph_edge_get_after_cmd_line(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->after_cmd_line;
}

char *qos_graph_edge_get_before_cmd_line(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->before_cmd_line;
}

char *qos_graph_edge_get_extra_device_opts(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->extra_device_opts;
}

char *qos_graph_edge_get_name(QOSGraphEdge *edge)
{
    if (!edge) {
        return NULL;
    }
    return edge->edge_name;
}

bool qos_graph_has_edge(const char *start, const char *dest)
{
    QOSGraphEdgeList *list = get_edgelist(start);
    QOSGraphEdge *e = search_list_edges(list, dest);
    return e != NULL;
}

QOSGraphNode *qos_graph_get_machine(const char *node)
{
    return search_machine(node);
}

bool qos_graph_has_machine(const char *node)
{
    QOSGraphNode *m = search_machine(node);
    return m != NULL;
}

void qos_print_graph(void)
{
    qos_graph_foreach_test_path(qos_print_cb);
}

void qos_graph_init(void)
{
    if (!node_table) {
        node_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                           destroy_string, destroy_node);
        create_node(QOS_ROOT, QNODE_DRIVER);
    }

    if (!edge_table) {
        edge_table = g_hash_table_new_full(g_str_hash, g_str_equal,
                                           destroy_string, destroy_edges);
    }
}

void qos_graph_destroy(void)
{
    if (node_table) {
        g_hash_table_destroy(node_table);
    }

    if (edge_table) {
        g_hash_table_destroy(edge_table);
    }

    node_table = NULL;
    edge_table = NULL;
}

void qos_node_destroy(void *key)
{
    g_hash_table_remove(node_table, key);
}

void qos_edge_destroy(void *key)
{
    g_hash_table_remove(edge_table, key);
}

void qos_add_test(const char *name, const char *interface,
                  QOSTestFunc test_func, QOSGraphTestOptions *opts)
{
    QOSGraphNode *node;
    char *test_name = g_strdup_printf("%s-tests/%s", interface, name);;
    QOSGraphTestOptions def_opts = { };

    if (!opts) {
        opts = &def_opts;
    }
    node = create_node(test_name, QNODE_TEST);
    node->u.test.function = test_func;
    node->u.test.arg = opts->arg;
    assert(!opts->edge.arg);
    assert(!opts->edge.size_arg);

    node->u.test.before = opts->before;
    node->u.test.subprocess = opts->subprocess;
    node->available = true;
    add_edge(interface, test_name, QEDGE_CONSUMED_BY, &opts->edge);
    g_free(test_name);
}

void qos_node_create_machine(const char *name, QOSCreateMachineFunc function)
{
    qos_node_create_machine_args(name, function, NULL);
}

void qos_node_create_machine_args(const char *name,
                                  QOSCreateMachineFunc function,
                                  const char *opts)
{
    QOSGraphNode *node = create_node(name, QNODE_MACHINE);
    build_machine_cmd_line(node, opts);
    node->u.machine.constructor = function;
    add_edge(QOS_ROOT, name, QEDGE_CONTAINS, NULL);
}

void qos_node_create_driver(const char *name, QOSCreateDriverFunc function)
{
    QOSGraphNode *node = create_node(name, QNODE_DRIVER);
    build_driver_cmd_line(node);
    node->u.driver.constructor = function;
}

void qos_node_contains(const char *container, const char *contained,
                       QOSGraphEdgeOptions *opts, ...)
{
    va_list va;

    if (opts == NULL) {
        add_edge(container, contained, QEDGE_CONTAINS, NULL);
        return;
    }

    va_start(va, opts);
    do {
        add_edge(container, contained, QEDGE_CONTAINS, opts);
        opts = va_arg(va, QOSGraphEdgeOptions *);
    } while (opts != NULL);

    va_end(va);
}

void qos_node_produces(const char *producer, const char *interface)
{
    create_interface(interface);
    add_edge(producer, interface, QEDGE_PRODUCES, NULL);
}

void qos_node_consumes(const char *consumer, const char *interface,
                       QOSGraphEdgeOptions *opts)
{
    create_interface(interface);
    add_edge(interface, consumer, QEDGE_CONSUMED_BY, opts);
}

void qos_graph_node_set_availability(const char *node, bool av)
{
    QOSGraphEdgeList *elist;
    QOSGraphNode *n = search_node(node);
    QOSGraphEdge *e, *next;
    if (!n) {
        return;
    }
    n->available = av;
    elist = get_edgelist(node);
    if (!elist) {
        return;
    }
    QSLIST_FOREACH_SAFE(e, elist, edge_list, next) {
        if (e->type == QEDGE_CONTAINS || e->type == QEDGE_PRODUCES) {
            qos_graph_node_set_availability(e->dest, av);
        }
    }
}

void qos_graph_foreach_test_path(QOSTestCallback fn)
{
    QOSGraphNode *root = qos_graph_get_node(QOS_ROOT);
    qos_traverse_graph(root, fn);
}

QOSGraphObject *qos_machine_new(QOSGraphNode *node, QTestState *qts)
{
    QOSGraphObject *obj;

    g_assert(node->type == QNODE_MACHINE);
    obj = node->u.machine.constructor(qts);
    obj->free = g_free;
    return obj;
}

QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
                               QGuestAllocator *alloc, void *arg)
{
    QOSGraphObject *obj;

    g_assert(node->type == QNODE_DRIVER);
    obj = node->u.driver.constructor(parent, alloc, arg);
    obj->free = g_free;
    return obj;
}

void qos_object_destroy(QOSGraphObject *obj)
{
    if (!obj) {
        return;
    }
    if (obj->destructor) {
        obj->destructor(obj);
    }
    if (obj->free) {
        obj->free(obj);
    }
}

void qos_object_queue_destroy(QOSGraphObject *obj)
{
    g_test_queue_destroy((GDestroyNotify) qos_object_destroy, obj);
}

void qos_object_start_hw(QOSGraphObject *obj)
{
    if (obj->start_hw) {
        obj->start_hw(obj);
    }
}

char *qos_get_machine_type(char *name)
{
    while (*name != '\0' && *name != '/') {
        name++;
    }

    if (!*name || !name[1]) {
        fprintf(stderr, "Machine name has to be of the form <arch>/<machine>\n");
        abort();
    }

    return name + 1;
}

void qos_delete_cmd_line(const char *name)
{
    QOSGraphNode *node = search_node(name);
    if (node) {
        g_free(node->command_line);
        node->command_line = NULL;
    }
}
