/*
 * 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)
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) {
		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);
