/*
 * 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 <zephyr/net/ppp.h>

#include "common.h"

#if defined(CONFIG_NET_L2_PPP)
#include <zephyr/net/ppp.h>
#include "ppp/ppp_internal.h"
#endif

static int cmd_net_ppp_ping(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_PPP)
	if (argv[1]) {
		int ret, idx = get_iface_idx(sh, argv[1]);

		if (idx < 0) {
			return -ENOEXEC;
		}

		ret = net_ppp_ping(idx, MSEC_PER_SEC * 1);
		if (ret < 0) {
			if (ret == -EAGAIN) {
				PR_INFO("PPP Echo-Req timeout.\n");
			} else if (ret == -ENODEV || ret == -ENOENT) {
				PR_INFO("Not a PPP interface (%d)\n", idx);
			} else {
				PR_INFO("PPP Echo-Req failed (%d)\n", ret);
			}
		} else {
			if (ret > 1000) {
				PR_INFO("%s%d msec\n",
					"Received PPP Echo-Reply in ",
					ret / 1000);
			} else {
				PR_INFO("%s%d usec\n",
					"Received PPP Echo-Reply in ", ret);
			}
		}
	} else {
		PR_INFO("PPP network interface must be given.\n");
		return -ENOEXEC;
	}
#else
	PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_PPP", "PPP");
#endif
	return 0;
}

static int cmd_net_ppp_status(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_PPP)
	int idx = 0;
	struct ppp_context *ctx;

	if (argv[1]) {
		idx = get_iface_idx(sh, argv[1]);
		if (idx < 0) {
			return -ENOEXEC;
		}
	}

	ctx = net_ppp_context_get(idx);
	if (!ctx) {
		PR_INFO("PPP context not found.\n");
		return -ENOEXEC;
	}

	PR("PPP phase           : %s (%d)\n", ppp_phase_str(ctx->phase),
								ctx->phase);
	PR("LCP state           : %s (%d)\n",
	   ppp_state_str(ctx->lcp.fsm.state), ctx->lcp.fsm.state);
	PR("LCP retransmits     : %u\n", ctx->lcp.fsm.retransmits);
	PR("LCP NACK loops      : %u\n", ctx->lcp.fsm.nack_loops);
	PR("LCP NACKs recv      : %u\n", ctx->lcp.fsm.recv_nack_loops);
	PR("LCP current id      : %d\n", ctx->lcp.fsm.id);
	PR("LCP ACK received    : %s\n", ctx->lcp.fsm.ack_received ?
								"yes" : "no");

#if defined(CONFIG_NET_IPV4)
	PR("IPCP state          : %s (%d)\n",
	   ppp_state_str(ctx->ipcp.fsm.state), ctx->ipcp.fsm.state);
	PR("IPCP retransmits    : %u\n", ctx->ipcp.fsm.retransmits);
	PR("IPCP NACK loops     : %u\n", ctx->ipcp.fsm.nack_loops);
	PR("IPCP NACKs recv     : %u\n", ctx->ipcp.fsm.recv_nack_loops);
	PR("IPCP current id     : %d\n", ctx->ipcp.fsm.id);
	PR("IPCP ACK received   : %s\n", ctx->ipcp.fsm.ack_received ?
								"yes" : "no");
#endif /* CONFIG_NET_IPV4 */

#if defined(CONFIG_NET_IPV6)
	PR("IPv6CP state        : %s (%d)\n",
	   ppp_state_str(ctx->ipv6cp.fsm.state), ctx->ipv6cp.fsm.state);
	PR("IPv6CP retransmits  : %u\n", ctx->ipv6cp.fsm.retransmits);
	PR("IPv6CP NACK loops   : %u\n", ctx->ipv6cp.fsm.nack_loops);
	PR("IPv6CP NACKs recv   : %u\n", ctx->ipv6cp.fsm.recv_nack_loops);
	PR("IPv6CP current id   : %d\n", ctx->ipv6cp.fsm.id);
	PR("IPv6CP ACK received : %s\n", ctx->ipv6cp.fsm.ack_received ?
								"yes" : "no");
#endif /* CONFIG_NET_IPV6 */

#if defined(CONFIG_NET_L2_PPP_PAP)
	PR("PAP state           : %s (%d)\n",
	   ppp_state_str(ctx->pap.fsm.state), ctx->pap.fsm.state);
	PR("PAP retransmits     : %u\n", ctx->pap.fsm.retransmits);
	PR("PAP NACK loops      : %u\n", ctx->pap.fsm.nack_loops);
	PR("PAP NACKs recv      : %u\n", ctx->pap.fsm.recv_nack_loops);
	PR("PAP current id      : %d\n", ctx->pap.fsm.id);
	PR("PAP ACK received    : %s\n", ctx->pap.fsm.ack_received ?
								"yes" : "no");
#endif /* CONFIG_NET_L2_PPP_PAP */

#else
	PR_INFO("Set %s to enable %s support.\n",
		"CONFIG_NET_L2_PPP and CONFIG_NET_PPP", "PPP");
#endif
	return 0;
}

#if defined(CONFIG_NET_SHELL_DYN_CMD_COMPLETION)

#define MAX_IFACE_HELP_STR_LEN sizeof("longbearername (0xabcd0123)")
#define MAX_IFACE_STR_LEN sizeof("xxx")

#if defined(CONFIG_NET_PPP)
static char iface_ppp_help_buffer[MAX_IFACE_COUNT][MAX_IFACE_HELP_STR_LEN];
static char iface_ppp_index_buffer[MAX_IFACE_COUNT][MAX_IFACE_STR_LEN];

static char *set_iface_ppp_index_buffer(size_t idx)
{
	struct net_if *iface = net_if_get_by_index(idx);

	/* Network interfaces start at 1 */
	if (idx == 0) {
		return "";
	}

	if (!iface) {
		return NULL;
	}

	if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) {
		return NULL;
	}

	snprintk(iface_ppp_index_buffer[idx], MAX_IFACE_STR_LEN, "%d", (uint8_t)idx);

	return iface_ppp_index_buffer[idx];
}

static char *set_iface_ppp_index_help(size_t idx)
{
	struct net_if *iface = net_if_get_by_index(idx);

	/* Network interfaces start at 1 */
	if (idx == 0) {
		return "";
	}

	if (!iface) {
		return NULL;
	}

	if (net_if_l2(iface) != &NET_L2_GET_NAME(PPP)) {
		return NULL;
	}

#if defined(CONFIG_NET_INTERFACE_NAME)
	char name[CONFIG_NET_INTERFACE_NAME_LEN + 1];

	net_if_get_name(iface, name, CONFIG_NET_INTERFACE_NAME_LEN);
	name[CONFIG_NET_INTERFACE_NAME_LEN] = '\0';

	snprintk(iface_ppp_help_buffer[idx], MAX_IFACE_HELP_STR_LEN,
		 "%s [%s] (%p)", name, iface2str(iface, NULL), iface);
#else
	snprintk(iface_ppp_help_buffer[idx], MAX_IFACE_HELP_STR_LEN,
		 "%s (%p)", iface2str(iface, NULL), iface);
#endif

	return iface_ppp_help_buffer[idx];
}

static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry);

SHELL_DYNAMIC_CMD_CREATE(iface_ppp_index, iface_ppp_index_get);

static void iface_ppp_index_get(size_t idx, struct shell_static_entry *entry)
{
	entry->handler = NULL;
	entry->help  = set_iface_ppp_index_help(idx);
	entry->subcmd = &iface_ppp_index;
	entry->syntax = set_iface_ppp_index_buffer(idx);
}

#define IFACE_PPP_DYN_CMD &iface_ppp_index
#else
#define IFACE_PPP_DYN_CMD NULL
#endif /* CONFIG_NET_PPP */

#else
#define IFACE_PPP_DYN_CMD NULL
#endif /* CONFIG_NET_SHELL_DYN_CMD_COMPLETION */

SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ppp,
	SHELL_CMD(ping, IFACE_PPP_DYN_CMD,
		  "'net ppp ping <index>' sends Echo-request to PPP interface.",
		  cmd_net_ppp_ping),
	SHELL_CMD(status, NULL,
		  "'net ppp status' prints information about PPP.",
		  cmd_net_ppp_status),
	SHELL_SUBCMD_SET_END
);

SHELL_SUBCMD_ADD((net), ppp, &net_cmd_ppp,
		 "PPP information.",
		 cmd_net_ppp_status, 1, 0);
