/*
 * Copyright (c) 2019 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_l2_ppp, CONFIG_NET_L2_PPP_LOG_LEVEL);

#include <stdlib.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_l2.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/ppp.h>
#include <zephyr/sys/iterable_sections.h>

#include "net_private.h"

#include "ppp_stats.h"
#include "ppp_internal.h"

static K_FIFO_DEFINE(tx_queue);

#if defined(CONFIG_NET_TC_THREAD_COOPERATIVE)
/* Lowest priority cooperative thread */
#define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NET_L2_PPP_THREAD_PRIO)
#else
#define THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NET_L2_PPP_THREAD_PRIO)
#endif

static void tx_handler(void *p1, void *p2, void *p3);

static K_THREAD_DEFINE(tx_handler_thread, CONFIG_NET_L2_PPP_TX_STACK_SIZE,
		       tx_handler, NULL, NULL, NULL,
		       THREAD_PRIORITY, 0, 0);

static const struct ppp_protocol_handler *ppp_lcp;

static void ppp_update_rx_stats(struct net_if *iface,
				struct net_pkt *pkt, size_t length)
{
#if defined(CONFIG_NET_STATISTICS_PPP)
	ppp_stats_update_bytes_rx(iface, length);
	ppp_stats_update_pkts_rx(iface);
#endif /* CONFIG_NET_STATISTICS_PPP */
}

static void ppp_update_tx_stats(struct net_if *iface,
				struct net_pkt *pkt, size_t length)
{
#if defined(CONFIG_NET_STATISTICS_PPP)
	ppp_stats_update_bytes_tx(iface, length);
	ppp_stats_update_pkts_tx(iface);
#endif /* CONFIG_NET_STATISTICS_PPP */
}

#if defined(CONFIG_NET_TEST)
typedef enum net_verdict (*ppp_l2_callback_t)(struct net_if *iface,
					      struct net_pkt *pkt);

static ppp_l2_callback_t testing_cb;

void ppp_l2_register_pkt_cb(ppp_l2_callback_t cb)
{
	testing_cb = cb;
}
#endif

static enum net_verdict process_ppp_msg(struct net_if *iface,
					struct net_pkt *pkt)
{
	struct ppp_context *ctx = net_if_l2_data(iface);
	enum net_verdict verdict = NET_DROP;
	uint16_t protocol;
	int ret;

	if (!ctx->is_ready_to_serve) {
		goto quit;
	}

	ret = net_pkt_read_be16(pkt, &protocol);
	if (ret < 0) {
		goto quit;
	}

	if ((IS_ENABLED(CONFIG_NET_IPV4) && protocol == PPP_IP) ||
	    (IS_ENABLED(CONFIG_NET_IPV6) && protocol == PPP_IPV6)) {
		/* Remove the protocol field so that IP packet processing
		 * continues properly in net_core.c:process_data()
		 */
		(void)net_buf_pull_be16(pkt->buffer);
		net_pkt_cursor_init(pkt);
		return NET_CONTINUE;
	}

	STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
		if (proto->protocol != protocol) {
			continue;
		}

		return proto->handler(ctx, iface, pkt);
	}

	switch (protocol) {
	case PPP_IP:
	case PPP_IPV6:
	case PPP_ECP:
	case PPP_CCP:
	case PPP_LCP:
	case PPP_IPCP:
	case PPP_IPV6CP:
		ppp_send_proto_rej(iface, pkt, protocol);
		break;
	default:
		break;
	}

	NET_DBG("%s protocol %s%s(0x%02x)",
		ppp_proto2str(protocol) ? "Unhandled" : "Unknown",
		ppp_proto2str(protocol),
		ppp_proto2str(protocol) ? " " : "",
		protocol);

quit:
	return verdict;
}

static enum net_verdict ppp_recv(struct net_if *iface,
				 struct net_pkt *pkt)
{
	enum net_verdict verdict;

#if defined(CONFIG_NET_TEST)
	/* If we are running a PPP unit test, then feed the packet
	 * back to test app for verification.
	 */
	if (testing_cb) {
		return testing_cb(iface, pkt);
	}
#endif

	ppp_update_rx_stats(iface, pkt, net_pkt_get_len(pkt));

	if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(pkt, "recv L2");
	}

	verdict = process_ppp_msg(iface, pkt);

	switch (verdict) {
	case NET_OK:
		net_pkt_unref(pkt);
		break;
	case NET_DROP:
		ppp_stats_update_drop_rx(iface);
		break;
	case NET_CONTINUE:
		break;
	}

	return verdict;
}

static int ppp_send(struct net_if *iface, struct net_pkt *pkt)
{
	const struct ppp_api *api = net_if_get_device(iface)->api;
	struct ppp_context *ctx = net_if_l2_data(iface);
	int ret;

	if (CONFIG_NET_L2_PPP_LOG_LEVEL >= LOG_LEVEL_DBG) {
		net_pkt_hexdump(pkt, "send L2");
	}

	/* If PPP is not yet ready, then just give error to caller as there
	 * is no way to send before the PPP handshake is finished.
	 */
	if (ctx->phase != PPP_RUNNING && !net_pkt_is_ppp(pkt)) {
		return -ENETDOWN;
	}

	ret = net_l2_send(api->send, net_if_get_device(iface), iface, pkt);
	if (!ret) {
		ret = net_pkt_get_len(pkt);
		ppp_update_tx_stats(iface, pkt, ret);
		net_pkt_unref(pkt);
	}

	return ret;
}

static enum net_l2_flags ppp_flags(struct net_if *iface)
{
	struct ppp_context *ctx = net_if_l2_data(iface);

	return ctx->ppp_l2_flags;
}

static void ppp_open_async(struct ppp_context *ctx)
{
	ppp_change_phase(ctx, PPP_ESTABLISH);

	if (ppp_lcp) {
		NET_DBG("Starting LCP");
		ppp_lcp->lower_up(ctx);
		ppp_lcp->open(ctx);
	}
}

static int ppp_up(struct net_if *iface)
{
	const struct ppp_api *ppp = net_if_get_device(iface)->api;

	if (ppp->start) {
		ppp->start(net_if_get_device(iface));
	}

	return 0;
}

static int ppp_lcp_close(struct ppp_context *ctx)
{
	if (ppp_lcp == NULL) {
		ppp_change_phase(ctx, PPP_DEAD);
	}

	if (ctx->phase == PPP_DEAD) {
		return 0;
	}

	k_sem_reset(&ctx->wait_ppp_link_terminated);
	ppp_lcp->close(ctx, "L2 Disabled");
	return k_sem_take(&ctx->wait_ppp_link_terminated, K_MSEC(CONFIG_NET_L2_PPP_TIMEOUT));
}

static void ppp_lcp_lower_down_async(struct ppp_context *ctx)
{
	if (ctx->phase == PPP_DEAD) {
		return;
	}

	if (ppp_lcp == NULL) {
		ppp_change_phase(ctx, PPP_DEAD);
	} else {
		ppp_lcp->lower_down(ctx);
	}
}

static int ppp_lcp_lower_down(struct ppp_context *ctx)
{
	if (ppp_lcp == NULL) {
		ppp_change_phase(ctx, PPP_DEAD);
	}

	if (ctx->phase == PPP_DEAD) {
		return 0;
	}

	k_sem_reset(&ctx->wait_ppp_link_down);
	ppp_lcp->lower_down(ctx);
	return k_sem_take(&ctx->wait_ppp_link_down, K_MSEC(CONFIG_NET_L2_PPP_TIMEOUT));
}

/* Bring down network interface by terminating all protocols */
static int ppp_down(struct net_if *iface)
{
	const struct ppp_api *ppp = net_if_get_device(iface)->api;
	struct ppp_context *ctx = net_if_l2_data(iface);

	if (net_if_is_carrier_ok(iface)) {
		/* Terminate protocols and close LCP */
		if (ppp_lcp_close(ctx) < 0) {
			return -EAGAIN;
		}
	} else {
		/* Terminate protocols */
		if (ppp_lcp_lower_down(ctx) < 0) {
			return -EAGAIN;
		}
	}

	if (ppp->stop) {
		/* Inform L2 PPP device that PPP link is down */
		ppp->stop(net_if_get_device(iface));
	}

	return 0;
}

static int ppp_enable(struct net_if *iface, bool state)
{
	struct ppp_context *ctx = net_if_l2_data(iface);
	int ret;

	/* Set the desired network interface state */
	ctx->is_enabled = state;

	/* Attempt to enter desired state */
	if (state) {
		ret = ppp_up(iface);
	} else {
		ret = ppp_down(iface);
	}

	if (ret < 0) {
		/* Reset the desired state */
		ctx->is_enabled = !state;
	}

	return ret;
}

NET_L2_INIT(PPP_L2, ppp_recv, ppp_send, ppp_enable, ppp_flags);

#if defined(CONFIG_NET_SHELL)
static int get_ppp_context(int idx, struct ppp_context **ctx,
			   struct net_if **iface)
{
	*iface = net_if_get_by_index(idx);

	if (!*iface) {
		return -ENOENT;
	}

	if (net_if_l2(*iface) != &NET_L2_GET_NAME(PPP)) {
		return -ENODEV;
	}

	*ctx = net_if_l2_data(*iface);

	return 0;
}

static void echo_reply_handler(void *user_data, size_t user_data_len)
{
	struct ppp_context *ctx = user_data;
	uint32_t end_time = k_cycle_get_32();
	uint32_t time_diff;

	time_diff = end_time - ctx->shell.echo_req_data;
	ctx->shell.echo_req_data =
		k_cyc_to_ns_floor64(time_diff) / 1000;

	k_sem_give(&ctx->shell.wait_echo_reply);
}

int net_ppp_ping(int idx, int32_t timeout)
{
	struct ppp_context *ctx;
	struct net_if *iface;
	int ret;

	ret = get_ppp_context(idx, &ctx, &iface);
	if (ret < 0) {
		return ret;
	}

	ctx->shell.echo_req_data = k_cycle_get_32();
	ctx->shell.echo_reply.cb = echo_reply_handler;
	ctx->shell.echo_reply.user_data = ctx;
	ctx->shell.echo_reply.user_data_len = sizeof(ctx);

	ret = ppp_send_pkt(&ctx->lcp.fsm, iface, PPP_ECHO_REQ, 0,
			   UINT_TO_POINTER(ctx->shell.echo_req_data),
			   sizeof(ctx->shell.echo_req_data));
	if (ret < 0) {
		return ret;
	}

	ret = k_sem_take(&ctx->shell.wait_echo_reply, K_MSEC(timeout));

	ctx->shell.echo_reply.cb = NULL;

	if (ret < 0) {
		return ret;
	}

	/* Returns amount of microseconds waited */
	return ctx->shell.echo_req_data;
}

struct ppp_context *net_ppp_context_get(int idx)
{
	struct ppp_context *ctx;
	struct net_if *iface;
	int ret;

	if (idx == 0) {
		iface = net_if_get_first_by_type(&NET_L2_GET_NAME(PPP));
		if (!iface) {
			return NULL;
		}

		return net_if_l2_data(iface);
	}

	ret = get_ppp_context(idx, &ctx, &iface);
	if (ret < 0) {
		return NULL;
	}

	return ctx;
}
#endif

const struct ppp_protocol_handler *ppp_lcp_get(void)
{
	return ppp_lcp;
}

void ppp_queue_pkt(struct net_pkt *pkt)
{
	k_fifo_put(&tx_queue, pkt);
}

static void tx_handler(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	struct net_pkt *pkt;
	int ret;

	NET_DBG("PPP TX started");

	k_thread_name_set(NULL, "ppp_tx");

	while (1) {
		pkt = k_fifo_get(&tx_queue, K_FOREVER);
		if (pkt == NULL) {
			continue;
		}

		ret = net_send_data(pkt);
		if (ret < 0) {
			net_pkt_unref(pkt);
		}
	}
}

static void net_ppp_mgmt_evt_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event,
				     struct net_if *iface)
{
	struct ppp_context *ctx;

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

	ctx = net_if_l2_data(iface);

	if (net_if_is_carrier_ok(iface)) {
		ppp_mgmt_raise_carrier_on_event(iface);
	} else {
		ppp_mgmt_raise_carrier_off_event(iface);
	}

	if (mgmt_event == NET_EVENT_IF_UP) {
		ppp_open_async(ctx);
		return;
	}

	if ((mgmt_event == NET_EVENT_IF_DOWN) && (!net_if_is_carrier_ok(iface))) {
		ppp_lcp_lower_down_async(ctx);
	}
}

void net_ppp_init(struct net_if *iface)
{
	struct ppp_context *ctx = net_if_l2_data(iface);
	uint8_t count = 0;

	NET_DBG("Initializing PPP L2 %p for iface %p", ctx, iface);

	memset(ctx, 0, sizeof(*ctx));

	ctx->ppp_l2_flags = NET_L2_MULTICAST | NET_L2_POINT_TO_POINT;
	ctx->iface = iface;
	k_sem_init(&ctx->wait_ppp_link_terminated, 0, 1);
	k_sem_init(&ctx->wait_ppp_link_down, 0, 1);

#if defined(CONFIG_NET_SHELL)
	k_sem_init(&ctx->shell.wait_echo_reply, 0, K_SEM_MAX_LIMIT);
#endif

	net_mgmt_init_event_callback(&ctx->mgmt_evt_cb, net_ppp_mgmt_evt_handler,
				     (NET_EVENT_IF_UP | NET_EVENT_IF_DOWN));

	net_mgmt_add_event_callback(&ctx->mgmt_evt_cb);

	STRUCT_SECTION_FOREACH(ppp_protocol_handler, proto) {
		if (proto->protocol == PPP_LCP) {
			ppp_lcp = proto;
		}

		proto->init(ctx);
		count++;
	}

	if (count == 0) {
		NET_ERR("There are no PPP protocols configured!");
		return;
	}

	if (ppp_lcp == NULL) {
		NET_ERR("No LCP found!");
		return;
	}

	ctx->is_ready_to_serve = true;
}
