/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);

#include <zephyr/zephyr.h>
#include <zephyr/linker/sections.h>
#include <ztest.h>
#include <zephyr/random/rand32.h>

#include <fcntl.h>

#include <zephyr/net/ethernet.h>
#include <zephyr/net/dummy.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/socket.h>

struct fake_dev_context {
	uint8_t mac_addr[sizeof(struct net_eth_addr)];
	struct net_if *iface;
};

static const char testing_data[] = "Tappara";

static int fake_dev_send(const struct device *dev, struct net_pkt *pkt)
{
	struct net_pkt *recv_pkt;
	int ret;

	ARG_UNUSED(dev);
	ARG_UNUSED(pkt);

	/* Loopback the data back to stack: */
	NET_DBG("Dummy device: Loopbacking data (%d bytes) to iface %d\n", net_pkt_get_len(pkt),
	    net_if_get_by_iface(net_pkt_iface(pkt)));

	recv_pkt = net_pkt_clone(pkt, K_NO_WAIT);

	k_sleep(K_MSEC(10)); /* Let the receiver run */

	ret = net_recv_data(net_pkt_iface(recv_pkt), recv_pkt);
	zassert_equal(ret, 0, "Cannot receive data (%d)", ret);
	return 0;
}

static uint8_t *fake_dev_get_mac(struct fake_dev_context *ctx)
{
	if (ctx->mac_addr[2] == 0x00) {
		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
		ctx->mac_addr[0] = 0x00;
		ctx->mac_addr[1] = 0x00;
		ctx->mac_addr[2] = 0x5E;
		ctx->mac_addr[3] = 0x00;
		ctx->mac_addr[4] = 0x53;
		ctx->mac_addr[5] = sys_rand32_get();
	}

	return ctx->mac_addr;
}

static void fake_dev_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct fake_dev_context *ctx = dev->data;
	uint8_t *mac = fake_dev_get_mac(ctx);

	net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);

	ctx->iface = iface;
}

int fake_dev_init(const struct device *dev)
{
	ARG_UNUSED(dev);

	return 0;
}

struct fake_dev_context fake_dev_context_data;

static struct dummy_api fake_dev_if_api = {
	.iface_api.init = fake_dev_iface_init,
	.send = fake_dev_send,
};

#define _ETH_L2_LAYER DUMMY_L2
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)

NET_DEVICE_INIT(fake_dev, "fake_dev", fake_dev_init, NULL, &fake_dev_context_data, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, &fake_dev_if_api, _ETH_L2_LAYER,
		_ETH_L2_CTX_TYPE, 127);

void test_setup(void)
{
	struct net_if *iface;
	struct in_addr in4addr_my = { { { 192, 168, 0, 2 } } };
	struct net_if_addr *ifaddr;

	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
	zassert_not_null(iface, "Could not get dummy iface");

	net_if_up(iface);

	ifaddr = net_if_ipv4_addr_add(iface, &in4addr_my, NET_ADDR_MANUAL, 0);
	zassert_not_null(ifaddr, "Could not add iface address");
}

void test_sckt_raw_packet_raw_ip(void)
{
	/* A test case for testing socket combo: AF_PACKET & SOCK_RAW & IPPROTO_RAW: */
	struct net_if *iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
	int recv_data_len, ret;
	struct sockaddr_ll dst = { 0 };
	char receive_buffer[128];
	int sock;

	sock = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
	zassert_true(sock >= 0, "Could not create a socket");

	dst.sll_ifindex = net_if_get_by_iface(iface);
	dst.sll_family = AF_PACKET;

	ret = bind(sock, (const struct sockaddr *)&dst, sizeof(struct sockaddr_ll));
	zassert_true(ret >= 0, "Could not bind the socket");

	/* Let's send some data: */
	ret = sendto(sock, testing_data, ARRAY_SIZE(testing_data), 0, (const struct sockaddr *)&dst,
		     sizeof(struct sockaddr_ll));
	zassert_true(ret > 0, "Could not send data");

	/* Receive the same data back: */
	recv_data_len = recv(sock, receive_buffer, sizeof(receive_buffer), 0);
	zassert_true(recv_data_len == ARRAY_SIZE(testing_data), "Expected data not received");

	NET_DBG("Received successfully data %s", log_strdup(receive_buffer));

	close(sock);
}

void test_main(void)
{
	ztest_test_suite(test_sckt_packet_raw_ip,
			 ztest_unit_test(test_setup),
			 ztest_unit_test(test_sckt_raw_packet_raw_ip));
	ztest_run_test_suite(test_sckt_packet_raw_ip);
}
