/*
 * 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.1 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/>
 */

#ifndef QGRAPH_H
#define QGRAPH_H

#include <gmodule.h>
#include "qemu/module.h"
#include "malloc.h"

/* maximum path length */
#define QOS_PATH_MAX_ELEMENT_SIZE 50

typedef struct QOSGraphObject QOSGraphObject;
typedef struct QOSGraphNode QOSGraphNode;
typedef struct QOSGraphEdge QOSGraphEdge;
typedef struct QOSGraphNodeOptions QOSGraphNodeOptions;
typedef struct QOSGraphEdgeOptions QOSGraphEdgeOptions;
typedef struct QOSGraphTestOptions QOSGraphTestOptions;

/* Constructor for drivers, machines and test */
typedef void *(*QOSCreateDriverFunc) (void *parent, QGuestAllocator *alloc,
                                      void *addr);
typedef void *(*QOSCreateMachineFunc) (QTestState *qts);
typedef void (*QOSTestFunc) (void *parent, void *arg, QGuestAllocator *alloc);

/* QOSGraphObject functions */
typedef void *(*QOSGetDriver) (void *object, const char *interface);
typedef QOSGraphObject *(*QOSGetDevice) (void *object, const char *name);
typedef void (*QOSDestructorFunc) (QOSGraphObject *object);
typedef void (*QOSStartFunct) (QOSGraphObject *object);

/* Test options functions */
typedef void *(*QOSBeforeTest) (GString *cmd_line, void *arg);

/**
 * SECTION: qgraph.h
 * @title: Qtest Driver Framework
 * @short_description: interfaces to organize drivers and tests
 *                     as nodes in a graph
 *
 * This Qgraph API provides all basic functions to create a graph
 * and instantiate nodes representing machines, drivers and tests
 * representing their relations with CONSUMES, PRODUCES, and CONTAINS
 * edges.
 *
 * The idea is to have a framework where each test asks for a specific
 * driver, and the framework takes care of allocating the proper devices
 * required and passing the correct command line arguments to QEMU.
 *
 * A node can be of four types:
 * - QNODE_MACHINE:   for example "arm/raspi2"
 * - QNODE_DRIVER:    for example "generic-sdhci"
 * - QNODE_INTERFACE: for example "sdhci" (interface for all "-sdhci" drivers)
 *                     an interface is not explicitly created, it will be auto-
 *                     matically instantiated when a node consumes or produces
 *                     it.
 * - QNODE_TEST:      for example "sdhci-test", consumes an interface and tests
 *                    the functions provided
 *
 * Notes for the nodes:
 * - QNODE_MACHINE: each machine struct must have a QGuestAllocator and
 *                  implement get_driver to return the allocator passing
 *                  "memory". The function can also return NULL if the
 *                  allocator is not set.
 * - QNODE_DRIVER:  driver names must be unique, and machines and nodes
 *                  planned to be "consumed" by other nodes must match QEMU
 *                  drivers name, otherwise they won't be discovered
 *
 * An edge relation between two nodes (drivers or machines) X and Y can be:
 * - X CONSUMES Y: Y can be plugged into X
 * - X PRODUCES Y: X provides the interface Y
 * - X CONTAINS Y: Y is part of X component
 *
 * Basic framework steps are the following:
 * - All nodes and edges are created in their respective
 *   machine/driver/test files
 * - The framework starts QEMU and asks for a list of available devices
 *   and machines (note that only machines and "consumed" nodes are mapped
 *   1:1 with QEMU devices)
 * - The framework walks the graph starting from the available machines and
 *   performs a Depth First Search for tests
 * - Once a test is found, the path is walked again and all drivers are
 *   allocated accordingly and the final interface is passed to the test
 * - The test is executed
 * - Unused objects are cleaned and the path discovery is continued
 *
 * Depending on the QEMU binary used, only some drivers/machines will be
 * available and only test that are reached by them will be executed.
 *
 * <example>
 *   <title>Creating new driver an its interface</title>
 *   <programlisting>
 #include "qgraph.h"

 struct My_driver {
     QOSGraphObject obj;
     Node_produced prod;
     Node_contained cont;
 }

 static void my_destructor(QOSGraphObject *obj)
 {
    g_free(obj);
 }

 static void my_get_driver(void *object, const char *interface) {
    My_driver *dev = object;
    if (!g_strcmp0(interface, "my_interface")) {
        return &dev->prod;
    }
    abort();
 }

 static void my_get_device(void *object, const char *device) {
    My_driver *dev = object;
    if (!g_strcmp0(device, "my_driver_contained")) {
        return &dev->cont;
    }
    abort();
 }

 static void *my_driver_constructor(void *node_consumed,
                                    QOSGraphObject *alloc)
 {
    My_driver dev = g_new(My_driver, 1);
    // get the node pointed by the produce edge
    dev->obj.get_driver = my_get_driver;
    // get the node pointed by the contains
    dev->obj.get_device = my_get_device;
    // free the object
    dev->obj.destructor = my_destructor;
    do_something_with_node_consumed(node_consumed);
    // set all fields of contained device
    init_contained_device(&dev->cont);
    return &dev->obj;
 }

 static void register_my_driver(void)
 {
     qos_node_create_driver("my_driver", my_driver_constructor);
     // contained drivers don't need a constructor,
     // they will be init by the parent.
     qos_node_create_driver("my_driver_contained", NULL);

    // For the sake of this example, assume machine x86_64/pc contains
    // "other_node".
    // This relation, along with the machine and "other_node" creation,
    // should be defined in the x86_64_pc-machine.c file.
    // "my_driver" will then consume "other_node"
    qos_node_contains("my_driver", "my_driver_contained");
    qos_node_produces("my_driver", "my_interface");
    qos_node_consumes("my_driver", "other_node");
 }
 *   </programlisting>
 * </example>
 *
 * In the above example, all possible types of relations are created:
 * node "my_driver" consumes, contains and produces other nodes.
 * more specifically:
 * x86_64/pc -->contains--> other_node <--consumes-- my_driver
 *                                                       |
 *                      my_driver_contained <--contains--+
 *                                                       |
 *                             my_interface <--produces--+
 *
 * or inverting the consumes edge in consumed_by:
 *
 * x86_64/pc -->contains--> other_node --consumed_by--> my_driver
 *                                                           |
 *                          my_driver_contained <--contains--+
 *                                                           |
 *                                 my_interface <--produces--+
 *
 * <example>
 *   <title>Creating new test</title>
 *   <programlisting>
 * #include "qgraph.h"
 *
 * static void my_test_function(void *obj, void *data)
 * {
 *    Node_produced *interface_to_test = obj;
 *    // test interface_to_test
 * }
 *
 * static void register_my_test(void)
 * {
 *    qos_add_test("my_interface", "my_test", my_test_function);
 * }
 *
 * libqos_init(register_my_test);
 *
 *   </programlisting>
 * </example>
 *
 * Here a new test is created, consuming "my_interface" node
 * and creating a valid path from a machine to a test.
 * Final graph will be like this:
 * x86_64/pc -->contains--> other_node <--consumes-- my_driver
 *                                                        |
 *                       my_driver_contained <--contains--+
 *                                                        |
 *        my_test --consumes--> my_interface <--produces--+
 *
 * or inverting the consumes edge in consumed_by:
 *
 * x86_64/pc -->contains--> other_node --consumed_by--> my_driver
 *                                                           |
 *                          my_driver_contained <--contains--+
 *                                                           |
 *        my_test <--consumed_by-- my_interface <--produces--+
 *
 * Assuming there the binary is
 * QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
 * a valid test path will be:
 * "/x86_64/pc/other_node/my_driver/my_interface/my_test".
 *
 * Additional examples are also in test-qgraph.c
 *
 * Command line:
 * Command line is built by using node names and optional arguments
 * passed by the user when building the edges.
 *
 * There are three types of command line arguments:
 * - in node      : created from the node name. For example, machines will
 *                  have "-M <machine>" to its command line, while devices
 *                  "-device <device>". It is automatically done by the
 *                   framework.
 * - after node   : added as additional argument to the node name.
 *                  This argument is added optionally when creating edges,
 *                  by setting the parameter @after_cmd_line and
 *                  @extra_edge_opts in #QOSGraphEdgeOptions.
 *                  The framework automatically adds
 *                  a comma before @extra_edge_opts,
 *                  because it is going to add attributes
 *                  after the destination node pointed by
 *                  the edge containing these options, and automatically
 *                  adds a space before @after_cmd_line, because it
 *                  adds an additional device, not an attribute.
 * - before node  : added as additional argument to the node name.
 *                  This argument is added optionally when creating edges,
 *                  by setting the parameter @before_cmd_line in
 *                  #QOSGraphEdgeOptions. This attribute
 *                  is going to add attributes before the destination node
 *                  pointed by the edge containing these options. It is
 *                  helpful to commands that are not node-representable,
 *                  such as "-fdsev" or "-netdev".
 *
 * While adding command line in edges is always used, not all nodes names are
 * used in every path walk: this is because the contained or produced ones
 * are already added by QEMU, so only nodes that "consumes" will be used to
 * build the command line. Also, nodes that will have { "abstract" : true }
 * as QMP attribute will loose their command line, since they are not proper
 * devices to be added in QEMU.
 *
 * Example:
 *
 QOSGraphEdgeOptions opts = {
     .arg = NULL,
     .size_arg = 0,
     .after_cmd_line = "-device other",
     .before_cmd_line = "-netdev something",
     .extra_edge_opts = "addr=04.0",
 };
 QOSGraphNode * node = qos_node_create_driver("my_node", constructor);
 qos_node_consumes_args("my_node", "interface", &opts);
 *
 * Will produce the following command line:
 * "-netdev something -device my_node,addr=04.0 -device other"
 */

/**
 * Edge options to be passed to the contains/consumes *_args function.
 */
struct QOSGraphEdgeOptions {
    void *arg;                    /*
                                   * optional arg that will be used by
                                   * dest edge
                                   */
    uint32_t size_arg;            /*
                                   * optional arg size that will be used by
                                   * dest edge
                                   */
    const char *extra_device_opts;/*
                                   *optional additional command line for dest
                                   * edge, used to add additional attributes
                                   * *after* the node command line, the
                                   * framework automatically prepends ","
                                   * to this argument.
                                   */
    const char *before_cmd_line;  /*
                                   * optional additional command line for dest
                                   * edge, used to add additional attributes
                                   * *before* the node command line, usually
                                   * other non-node represented commands,
                                   * like "-fdsev synt"
                                   */
    const char *after_cmd_line;   /*
                                   * optional extra command line to be added
                                   * after the device command. This option
                                   * is used to add other devices
                                   * command line that depend on current node.
                                   * Automatically prepends " " to this
                                   * argument
                                   */
    const char *edge_name;        /*
                                   * optional edge to differentiate multiple
                                   * devices with same node name
                                   */
};

/**
 * Test options to be passed to the test functions.
 */
struct QOSGraphTestOptions {
    QOSGraphEdgeOptions edge;   /* edge arguments that will be used by test.
                                 * Note that test *does not* use edge_name,
                                 * and uses instead arg and size_arg as
                                 * data arg for its test function.
                                 */
    void *arg;                  /* passed to the .before function, or to the
                                 * test function if there is no .before
                                 * function
                                 */
    QOSBeforeTest before;       /* executed before the test. Can add
                                 * additional parameters to the command line
                                 * and modify the argument to the test function.
                                 */
    bool subprocess;            /* run the test in a subprocess */
};

/**
 * Each driver, test or machine of this framework will have a
 * QOSGraphObject as first field.
 *
 * This set of functions offered by QOSGraphObject are executed
 * in different stages of the framework:
 * - get_driver / get_device : Once a machine-to-test path has been
 * found, the framework traverses it again and allocates all the
 * nodes, using the provided constructor. To satisfy their relations,
 * i.e. for produces or contains, where a struct constructor needs
 * an external parameter represented by the previous node,
 * the framework will call get_device (for contains) or
 * get_driver (for produces), depending on the edge type, passing
 * them the name of the next node to be taken and getting from them
 * the corresponding pointer to the actual structure of the next node to
 * be used in the path.
 *
 * - start_hw: This function is executed after all the path objects
 * have been allocated, but before the test is run. It starts the hw, setting
 * the initial configurations (*_device_enable) and making it ready for the
 * test.
 *
 * - destructor: Opposite to the node constructor, destroys the object.
 * This function is called after the test has been executed, and performs
 * a complete cleanup of each node allocated field. In case no constructor
 * is provided, no destructor will be called.
 *
 */
struct QOSGraphObject {
    /* for produces edges, returns void * */
    QOSGetDriver get_driver;
    /* for contains edges, returns a QOSGraphObject * */
    QOSGetDevice get_device;
    /* start the hw, get ready for the test */
    QOSStartFunct start_hw;
    /* destroy this QOSGraphObject */
    QOSDestructorFunc destructor;
    /* free the memory associated to the QOSGraphObject and its contained
     * children */
    GDestroyNotify free;
};

/**
 * qos_graph_init(): initialize the framework, creates two hash
 * tables: one for the nodes and another for the edges.
 */
void qos_graph_init(void);

/**
 * qos_graph_destroy(): deallocates all the hash tables,
 * freeing all nodes and edges.
 */
void qos_graph_destroy(void);

/**
 * qos_node_destroy(): removes and frees a node from the,
 * nodes hash table.
 */
void qos_node_destroy(void *key);

/**
 * qos_edge_destroy(): removes and frees an edge from the,
 * edges hash table.
 */
void qos_edge_destroy(void *key);

/**
 * qos_add_test(): adds a test node @name to the nodes hash table.
 *
 * The test will consume a @interface node, and once the
 * graph walking algorithm has found it, the @test_func will be
 * executed. It also has the possibility to
 * add an optional @opts (see %QOSGraphNodeOptions).
 *
 * For tests, opts->edge.arg and size_arg represent the arg to pass
 * to @test_func
 */
void qos_add_test(const char *name, const char *interface,
                  QOSTestFunc test_func,
                  QOSGraphTestOptions *opts);

/**
 * qos_node_create_machine(): creates the machine @name and
 * adds it to the node hash table.
 *
 * This node will be of type QNODE_MACHINE and have @function
 * as constructor
 */
void qos_node_create_machine(const char *name, QOSCreateMachineFunc function);

/**
 * qos_node_create_machine_args(): same as qos_node_create_machine,
 * but with the possibility to add an optional ", @opts" after -M machine
 * command line.
 */
void qos_node_create_machine_args(const char *name,
                                  QOSCreateMachineFunc function,
                                  const char *opts);

/**
 * qos_node_create_driver(): creates the driver @name and
 * adds it to the node hash table.
 *
 * This node will be of type QNODE_DRIVER and have @function
 * as constructor
 */
void qos_node_create_driver(const char *name, QOSCreateDriverFunc function);

/**
 * qos_node_contains(): creates one or more edges of type QEDGE_CONTAINS
 * and adds them to the edge list mapped to @container in the
 * edge hash table.
 *
 * The edges will have @container as source and @contained as destination.
 *
 * If @opts is NULL, a single edge will be added with no options.
 * If @opts is non-NULL, the arguments after @contained represent a
 * NULL-terminated list of %QOSGraphEdgeOptions structs, and an
 * edge will be added for each of them.
 *
 * This function can be useful when there are multiple devices
 * with the same node name contained in a machine/other node
 *
 * For example, if "arm/raspi2" contains 2 "generic-sdhci"
 * devices, the right commands will be:
 * qos_node_create_machine("arm/raspi2");
 * qos_node_create_driver("generic-sdhci", constructor);
 * //assume rest of the fields are set NULL
 * QOSGraphEdgeOptions op1 = { .edge_name = "emmc" };
 * QOSGraphEdgeOptions op2 = { .edge_name = "sdcard" };
 * qos_node_contains("arm/raspi2", "generic-sdhci", &op1, &op2, NULL);
 *
 * Of course this also requires that the @container's get_device function
 * should implement a case for "emmc" and "sdcard".
 *
 * For contains, op1.arg and op1.size_arg represent the arg to pass
 * to @contained constructor to properly initialize it.
 */
void qos_node_contains(const char *container, const char *contained,
                       QOSGraphEdgeOptions *opts, ...);

/**
 * qos_node_produces(): creates an edge of type QEDGE_PRODUCES and
 * adds it to the edge list mapped to @producer in the
 * edge hash table.
 *
 * This edge will have @producer as source and @interface as destination.
 */
void qos_node_produces(const char *producer, const char *interface);

/**
 * qos_node_consumes():  creates an edge of type QEDGE_CONSUMED_BY and
 * adds it to the edge list mapped to @interface in the
 * edge hash table.
 *
 * This edge will have @interface as source and @consumer as destination.
 * It also has the possibility to add an optional @opts
 * (see %QOSGraphEdgeOptions)
 */
void qos_node_consumes(const char *consumer, const char *interface,
                       QOSGraphEdgeOptions *opts);

/**
 * qos_invalidate_command_line(): invalidates current command line, so that
 * qgraph framework cannot try to cache the current command line and
 * forces QEMU to restart.
 */
void qos_invalidate_command_line(void);

/**
 * qos_get_current_command_line(): return the command line required by the
 * machine and driver objects.  This is the same string that was passed to
 * the test's "before" callback, if any.
 */
const char *qos_get_current_command_line(void);

/**
 * qos_allocate_objects():
 * @qts: The #QTestState that will be referred to by the machine object.
 * @alloc: Where to store the allocator for the machine object, or %NULL.
 *
 * Allocate driver objects for the current test
 * path, but relative to the QTestState @qts.
 *
 * Returns a test object just like the one that was passed to
 * the test function, but relative to @qts.
 */
void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc);

/**
 * qos_object_destroy(): calls the destructor for @obj
 */
void qos_object_destroy(QOSGraphObject *obj);

/**
 * qos_object_queue_destroy(): queue the destructor for @obj so that it is
 * called at the end of the test
 */
void qos_object_queue_destroy(QOSGraphObject *obj);

/**
 * qos_object_start_hw(): calls the start_hw function for @obj
 */
void qos_object_start_hw(QOSGraphObject *obj);

/**
 * qos_machine_new(): instantiate a new machine node
 * @node: A machine node to be instantiated
 * @qts: The #QTestState that will be referred to by the machine object.
 *
 * Returns a machine object.
 */
QOSGraphObject *qos_machine_new(QOSGraphNode *node, QTestState *qts);

/**
 * qos_machine_new(): instantiate a new driver node
 * @node: A driver node to be instantiated
 * @parent: A #QOSGraphObject to be consumed by the new driver node
 * @alloc: An allocator to be used by the new driver node.
 * @arg: The argument for the consumed-by edge to @node.
 *
 * Calls the constructor for the driver object.
 */
QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
                               QGuestAllocator *alloc, void *arg);


#endif
