/* SPDX-License-Identifier: LGPL-2.1-or-later */
/***
  Copyright © 2014 Axis Communications AB. All rights reserved.
***/

#include <errno.h>
#include <netinet/if_ether.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#include "sd-ipv4ll.h"

#include "arp-util.h"
#include "fd-util.h"
#include "socket-util.h"
#include "tests.h"

static bool verbose = false;
static bool extended = false;
static int test_fd[2];

static int basic_request_handler_bind = 0;
static int basic_request_handler_stop = 0;
static void* basic_request_handler_userdata = (void*) 0xCABCAB;

static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
        assert_se(userdata == basic_request_handler_userdata);

        switch (event) {
                case SD_IPV4LL_EVENT_STOP:
                        basic_request_handler_stop = 1;
                        break;
                case SD_IPV4LL_EVENT_BIND:
                        basic_request_handler_bind = 1;
                        break;
                default:
                        assert_se(0);
                        break;
        }
}

int arp_send_packet(
                int fd,
                int ifindex,
                const struct in_addr *pa,
                const struct ether_addr *ha,
                bool announce) {

        struct ether_arp ea = {};

        assert_se(fd >= 0);
        assert_se(ifindex > 0);
        assert_se(pa);
        assert_se(ha);

        if (send(fd, &ea, sizeof(struct ether_arp), 0) < 0)
                return -errno;

        return 0;
}

int arp_update_filter(int fd, const struct in_addr *a, const struct ether_addr *eth_mac) {
        return 0;
}

int arp_network_bind_raw_socket(int ifindex, const struct in_addr *a, const struct ether_addr *eth_mac) {
        if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
                return -errno;

        return test_fd[0];
}

static void test_public_api_setters(sd_event *e) {
        struct in_addr address = {};
        uint64_t seed = 0;
        sd_ipv4ll *ll;
        struct ether_addr mac_addr = {
                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};

        if (verbose)
                printf("* %s\n", __func__);

        assert_se(sd_ipv4ll_new(&ll) == 0);
        assert_se(ll);

        assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);

        assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);

        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(169U << 24 | 254U << 16);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(0x00FF);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
        address.s_addr |= htobe32(0xF000);
        assert_se(sd_ipv4ll_set_address(ll, &address) == 0);
        address.s_addr |= htobe32(0x0F00);
        assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);

        assert_se(sd_ipv4ll_set_address_seed(NULL, seed) == -EINVAL);
        assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);

        assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
        assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);

        assert_se(sd_ipv4ll_set_ifindex(NULL, -1) == -EINVAL);
        assert_se(sd_ipv4ll_set_ifindex(ll, -1) == -EINVAL);
        assert_se(sd_ipv4ll_set_ifindex(ll, -99) == -EINVAL);
        assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);

        assert_se(sd_ipv4ll_ref(ll) == ll);
        assert_se(sd_ipv4ll_unref(ll) == NULL);

        /* Cleanup */
        assert_se(sd_ipv4ll_unref(ll) == NULL);
}

static void test_basic_request(sd_event *e, const struct in_addr *start_address) {

        sd_ipv4ll *ll;
        struct ether_arp arp;
        struct ether_addr mac_addr = {
                .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};

        if (verbose)
                printf("* %s\n", __func__);

        assert_se(sd_ipv4ll_new(&ll) == 0);
        if (in4_addr_is_set(start_address))
                assert_se(sd_ipv4ll_set_address(ll, start_address) >= 0);
        assert_se(sd_ipv4ll_start(ll) == -EINVAL);

        assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
        assert_se(sd_ipv4ll_start(ll) == -EINVAL);

        assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
        assert_se(sd_ipv4ll_start(ll) == -EINVAL);

        assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
                                         basic_request_handler_userdata) == 0);
        assert_se(sd_ipv4ll_start(ll) == -EINVAL);

        assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);
        assert_se(sd_ipv4ll_start(ll) == 1);

        sd_event_run(e, UINT64_MAX);
        assert_se(sd_ipv4ll_start(ll) == 0);

        assert_se(sd_ipv4ll_is_running(ll));

        /* PROBE */
        sd_event_run(e, UINT64_MAX);
        assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));

        if (extended) {
                /* PROBE */
                sd_event_run(e, UINT64_MAX);
                assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));

                /* PROBE */
                sd_event_run(e, UINT64_MAX);
                assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));

                sd_event_run(e, UINT64_MAX);
                assert_se(basic_request_handler_bind == 1);

                if (in4_addr_is_set(start_address)) {
                        struct in_addr address;

                        assert_se(sd_ipv4ll_get_address(ll, &address) >= 0);
                        assert_se(start_address->s_addr == address.s_addr);
                }
        }

        sd_ipv4ll_stop(ll);
        assert_se(basic_request_handler_stop == 1);

        /* Cleanup */
        assert_se(sd_ipv4ll_unref(ll) == NULL);
        safe_close(test_fd[1]);
}

int main(int argc, char *argv[]) {
        struct in_addr start_address = {};
        _cleanup_(sd_event_unrefp) sd_event *e = NULL;

        test_setup_logging(LOG_DEBUG);

        assert_se(sd_event_new(&e) >= 0);

        test_public_api_setters(e);
        test_basic_request(e, &start_address);

        basic_request_handler_bind = 0;
        basic_request_handler_stop = 0;
        start_address.s_addr = htobe32(169U << 24 | 254U << 16 | 1U << 8 | 2U);
        test_basic_request(e, &start_address);

        return 0;
}
