/*
 * vmnet-bridged.m
 *
 * Copyright(c) 2022 Vladislav Yaroshchuk <vladislav.yaroshchuk@jetbrains.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qapi/qapi-types-net.h"
#include "qapi/error.h"
#include "clients.h"
#include "vmnet_int.h"

#include <vmnet/vmnet.h>


static bool validate_ifname(const char *ifname)
{
    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
    bool match = false;
    if (!xpc_array_get_count(shared_if_list)) {
        goto done;
    }

    match = !xpc_array_apply(
        shared_if_list,
        ^bool(size_t index, xpc_object_t value) {
            return strcmp(xpc_string_get_string_ptr(value), ifname) != 0;
        });

done:
    xpc_release(shared_if_list);
    return match;
}


static char* get_valid_ifnames(void)
{
    xpc_object_t shared_if_list = vmnet_copy_shared_interface_list();
    __block char *if_list = NULL;
    __block char *if_list_prev = NULL;

    if (!xpc_array_get_count(shared_if_list)) {
        goto done;
    }

    xpc_array_apply(
        shared_if_list,
        ^bool(size_t index, xpc_object_t value) {
            /* build list of strings like "en0 en1 en2 " */
            if_list = g_strconcat(xpc_string_get_string_ptr(value),
                                  " ",
                                  if_list_prev,
                                  NULL);
            g_free(if_list_prev);
            if_list_prev = if_list;
            return true;
        });

done:
    xpc_release(shared_if_list);
    return if_list;
}


static bool validate_options(const Netdev *netdev, Error **errp)
{
    const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
    char* if_list;

    if (!validate_ifname(options->ifname)) {
        if_list = get_valid_ifnames();
        if (if_list) {
            error_setg(errp,
                       "unsupported ifname '%s', expected one of [ %s]",
                       options->ifname,
                       if_list);
            g_free(if_list);
        } else {
            error_setg(errp,
                       "unsupported ifname '%s', no supported "
                       "interfaces available",
                       options->ifname);
        }
        return false;
    }

    return true;
}


static xpc_object_t build_if_desc(const Netdev *netdev)
{
    const NetdevVmnetBridgedOptions *options = &(netdev->u.vmnet_bridged);
    xpc_object_t if_desc = xpc_dictionary_create(NULL, NULL, 0);

    xpc_dictionary_set_uint64(if_desc,
                              vmnet_operation_mode_key,
                              VMNET_BRIDGED_MODE
    );

    xpc_dictionary_set_string(if_desc,
                              vmnet_shared_interface_name_key,
                              options->ifname);

    xpc_dictionary_set_bool(if_desc,
                            vmnet_enable_isolation_key,
                            options->isolated);

    return if_desc;
}


static NetClientInfo net_vmnet_bridged_info = {
    .type = NET_CLIENT_DRIVER_VMNET_BRIDGED,
    .size = sizeof(VmnetState),
    .receive = vmnet_receive_common,
    .cleanup = vmnet_cleanup_common,
};


int net_init_vmnet_bridged(const Netdev *netdev, const char *name,
                           NetClientState *peer, Error **errp)
{
    NetClientState *nc = qemu_new_net_client(&net_vmnet_bridged_info,
                                             peer, "vmnet-bridged", name);
    xpc_object_t if_desc;
    int result = -1;

    if (!validate_options(netdev, errp)) {
        return result;
    }

    if_desc = build_if_desc(netdev);
    result = vmnet_if_create(nc, if_desc, errp);
    xpc_release(if_desc);
    return result;
}
