/*
 * Copyright (c) 2016 Intel Corporation
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_shell);

#include <stdlib.h>

#include "net_shell_private.h"

#include <zephyr/net/capture.h>

#if defined(CONFIG_NET_CAPTURE)
#define DEFAULT_DEV_NAME "NET_CAPTURE0"
static const struct device *capture_dev;

static void get_address_str(const struct sockaddr *addr,
			    char *str, int str_len)
{
	if (IS_ENABLED(CONFIG_NET_IPV6) && addr->sa_family == AF_INET6) {
		snprintk(str, str_len, "[%s]:%u",
			 net_sprint_ipv6_addr(&net_sin6(addr)->sin6_addr),
			 ntohs(net_sin6(addr)->sin6_port));

	} else if (IS_ENABLED(CONFIG_NET_IPV4) && addr->sa_family == AF_INET) {
		snprintk(str, str_len, "%s:%d",
			 net_sprint_ipv4_addr(&net_sin(addr)->sin_addr),
			 ntohs(net_sin(addr)->sin_port));

	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) &&
		   addr->sa_family == AF_PACKET) {
		snprintk(str, str_len, "AF_PACKET");
	} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) &&
		   addr->sa_family == AF_CAN) {
		snprintk(str, str_len, "AF_CAN");
	} else if (addr->sa_family == AF_UNSPEC) {
		snprintk(str, str_len, "AF_UNSPEC");
	} else {
		snprintk(str, str_len, "AF_UNK(%d)", addr->sa_family);
	}
}

static void capture_cb(struct net_capture_info *info, void *user_data)
{
	struct net_shell_user_data *data = user_data;
	const struct shell *sh = data->sh;
	int *count = data->user_data;
	char addr_local[ADDR_LEN + 7];
	char addr_peer[ADDR_LEN + 7];

	if (*count == 0) {
		PR("      \t\tCapture  Tunnel\n");
		PR("Device\t\tiface    iface   Local\t\t\tPeer\n");
	}

	get_address_str(info->local, addr_local, sizeof(addr_local));
	get_address_str(info->peer, addr_peer, sizeof(addr_peer));

	PR("%s\t%c        %d      %s\t%s\n", info->capture_dev->name,
	   info->is_enabled ?
	   (net_if_get_by_iface(info->capture_iface) + '0') : '-',
	   net_if_get_by_iface(info->tunnel_iface),
	   addr_local, addr_peer);

	(*count)++;
}
#endif

static int cmd_net_capture(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_CAPTURE)
	bool ret;

	if (capture_dev == NULL) {
		capture_dev = device_get_binding(DEFAULT_DEV_NAME);
	}

	if (capture_dev == NULL) {
		PR_INFO("Network packet capture %s\n", "not configured");
	} else {
		struct net_shell_user_data user_data;
		int count = 0;

		ret = net_capture_is_enabled(capture_dev);
		PR_INFO("Network packet capture %s\n",
			ret ? "enabled" : "disabled");

		user_data.sh = sh;
		user_data.user_data = &count;

		net_capture_foreach(capture_cb, &user_data);
	}
#else
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_CAPTURE", "network packet capture");
#endif
	return 0;
}

static int cmd_net_capture_setup(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_CAPTURE)
	int ret, arg = 1;
	const char *remote, *local, *peer;

	remote = argv[arg++];
	if (!remote) {
		PR_WARNING("Remote IP address not specified.\n");
		return -ENOEXEC;
	}

	local = argv[arg++];
	if (!local) {
		PR_WARNING("Local IP address not specified.\n");
		return -ENOEXEC;
	}

	peer = argv[arg];
	if (!peer) {
		PR_WARNING("Peer IP address not specified.\n");
		return -ENOEXEC;
	}

	if (capture_dev != NULL) {
		PR_INFO("Capture already setup, cleaning up settings.\n");
		net_capture_cleanup(capture_dev);
		capture_dev = NULL;
	}

	ret = net_capture_setup(remote, local, peer, &capture_dev);
	if (ret < 0) {
		PR_WARNING("Capture cannot be setup (%d)\n", ret);
		return -ENOEXEC;
	}

	PR_INFO("Capture setup done, next enable it by "
		"\"net capture enable <idx>\"\n");
#else
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_CAPTURE", "network packet capture");
#endif

	return 0;
}

static int cmd_net_capture_cleanup(const struct shell *sh, size_t argc, char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

#if defined(CONFIG_NET_CAPTURE)
	int ret;

	if (capture_dev == NULL) {
		return 0;
	}

	ret = net_capture_cleanup(capture_dev);
	if (ret < 0) {
		PR_WARNING("Capture %s failed (%d)\n", "cleanup", ret);
		return -ENOEXEC;
	}

	capture_dev = NULL;
#else
	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_CAPTURE", "network packet capture");
#endif

	return 0;
}

static int cmd_net_capture_enable(const struct shell *sh, size_t argc, char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

#if defined(CONFIG_NET_CAPTURE)
	int ret, arg = 1, if_index;
	struct net_if *iface;

	if (capture_dev == NULL) {
		return 0;
	}

	if (argv[arg] == NULL) {
		PR_WARNING("Interface index is missing. Please give interface "
			   "what you want to monitor\n");
		return -ENOEXEC;
	}

	if_index = atoi(argv[arg++]);
	if (if_index == 0) {
		PR_WARNING("Interface index %d is invalid.\n", if_index);
		return -ENOEXEC;
	}

	iface = net_if_get_by_index(if_index);
	if (iface == NULL) {
		PR_WARNING("No such interface with index %d\n", if_index);
		return -ENOEXEC;
	}

	ret = net_capture_enable(capture_dev, iface);
	if (ret < 0) {
		PR_WARNING("Capture %s failed (%d)\n", "enable", ret);
		return -ENOEXEC;
	}
#else
	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_CAPTURE", "network packet capture");
#endif

	return 0;
}

static int cmd_net_capture_disable(const struct shell *sh, size_t argc, char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

#if defined(CONFIG_NET_CAPTURE)
	int ret;

	if (capture_dev == NULL) {
		return 0;
	}

	ret = net_capture_disable(capture_dev);
	if (ret < 0) {
		PR_WARNING("Capture %s failed (%d)\n", "disable", ret);
		return -ENOEXEC;
	}
#else
	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_CAPTURE", "network packet capture");
#endif

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_capture,
	SHELL_CMD(setup, NULL, "Setup network packet capture.\n"
		  "'net capture setup <remote-ip-addr> <local-addr> <peer-addr>'\n"
		  "<remote> is the (outer) endpoint IP address,\n"
		  "<local> is the (inner) local IP address,\n"
		  "<peer> is the (inner) peer IP address\n"
		  "Local and Peer addresses can have UDP port number in them (optional)\n"
		  "like 198.0.51.2:9000 or [2001:db8:100::2]:4242",
		  cmd_net_capture_setup),
	SHELL_CMD(cleanup, NULL, "Cleanup network packet capture.",
		  cmd_net_capture_cleanup),
	SHELL_CMD(enable, NULL, "Enable network packet capture for a given "
		  "network interface.\n"
		  "'net capture enable <interface index>'",
		  cmd_net_capture_enable),
	SHELL_CMD(disable, NULL, "Disable network packet capture.",
		  cmd_net_capture_disable),
	SHELL_SUBCMD_SET_END
);

SHELL_SUBCMD_ADD((net), capture, &net_cmd_capture,
		 "Configure network packet capture.", cmd_net_capture, 1, 0);
