/*
 * Copyright 2018, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(DATA61_GPL)
 */

#pragma once

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

#include <net/ethernet.h>

#include <virtqueue.h>

/* TODO: Need to introduce or paramterise this variable into the
 * build system
 */
#define VSWITCH_NUM_NODES           (4)
/* MAC address print format*/
#define PR_MAC802_ADDR                      "%x:%x:%x:%x:%x:%x"
/* Expects a *pointer* to a struct ether_addr */
#define PR_MAC802_ADDR_ARGS(a)              (a)->ether_addr_octet[0], \
                                            (a)->ether_addr_octet[1], \
                                            (a)->ether_addr_octet[2], \
                                            (a)->ether_addr_octet[3], \
                                            (a)->ether_addr_octet[4], \
                                            (a)->ether_addr_octet[5]

/*
 * Represents the virtqueues used in a given link between
 * two nodes.
 */
typedef struct vswitch_virtqueues_ {
    virtqueue_driver_t *send_queue;
    virtqueue_device_t *recv_queue;
} vswitch_virtqueues_t;

extern struct ether_addr null_macaddr, bcast_macaddr;

static inline bool
mac802_addr_eq(struct ether_addr *addr0,
               struct ether_addr *addr1)
{
    for (int i = 0; i < ETH_ALEN; i++) {
        if (addr0->ether_addr_octet[i] != addr1->ether_addr_octet[i]) {
            return false;
        }
    }
    return true;
}

static inline bool
mac802_addr_eq_bcast(struct ether_addr *addr)
{
    return mac802_addr_eq(addr, &bcast_macaddr);
}

typedef struct vswitch_node_ {
    struct ether_addr addr;
    vswitch_virtqueues_t virtqueues;
} vswitch_node_t;

/*
 * Each component participating in a vswitch topology should have a
 * MAC address assigned to them. It is expected during the initialisation of
 * these nodes they will call "vswitch_connect()" to register the
 * MAC address of the other nodes it is linked to. This will inturn
 * populate the vswitch_t data structure.
 *
 * Furthermore, each node is expected to have a send and recieve
 * virtqueue for each destination node it has connection to.
 */
typedef struct vswitch_ {
    int n_connected;
    vswitch_node_t nodes[VSWITCH_NUM_NODES];
} vswitch_t;

/** Initialize an instance of this library
 * @param lib Uninitialized handle for a prospective instance of this library.
 * @return 0 on success.
 */
int vswitch_init(vswitch_t *lib);

/** Initializes metadata to track a destination node connected to the VSWITCH
 * bcast domain.
 *
 * During initialization of each component it is expected to
 * call this function to register the MAC address and virtqueues of all
 * the other nodes it is connected to.
 *
 * @param lib An initialized handle an instance of this library.
 * @param guest_macaddr A pointer to a mac address for the Guest VM being
 *                      registered.
 * @param send_virtqueue An initialized handle to a send virtqueue for
 *                        the destination being registered.
 * @param recv_virtqueue An initialized handle to a recieve virtqueue for
 *                        the destination being registered.
 */
int vswitch_connect(vswitch_t *lib,
                    struct ether_addr *guest_macaddr,
                    virtqueue_driver_t *send_virtqueue,
                    virtqueue_device_t *recv_virtqueue);

/** Checks to see if a destination with the MAC address "mac" has been registered with
 * the library.
 *
 * @param lib Initialized instance of this library.
 * @param mac Mac address of the destination to be looked up.
 * @return Positive integer if the specified MAC address has been registered.
 *         Negative integer if not.
 */
int vswitch_get_destnode_index_by_macaddr(vswitch_t *lib,
                                          struct ether_addr *mac);

/** Used to iterate through all the registered destinations indiscriminately.
 * @param lib Initialized instance of this library.
 * @param index Positive integer from 0 to VSWITCH_NUM_NODES.
 * @return NULL if an invalid index is supplied. Non-NULL if a valid index is
 *              supplied.
 */
vswitch_node_t *vswitch_get_destnode_by_index(vswitch_t *lib,
                                              size_t index);

static inline vswitch_node_t *
vswitch_get_destnode_by_macaddr(vswitch_t *lib,
                                struct ether_addr *mac)
{
    int idx = vswitch_get_destnode_index_by_macaddr(lib, mac);
    if (idx < 0) {
        return NULL;
    }

    return vswitch_get_destnode_by_index(lib, idx);
}
