/*
 * Copyright (c) 2019-2020 Grinn
 *
 * SPDX-License-Identifier: Apache-2.0
 */

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

#include <zephyr/net/net_pkt.h>

#include "ppp_internal.h"

static enum net_verdict pap_handle(struct ppp_context *ctx,
				   struct net_if *iface,
				   struct net_pkt *pkt)
{
	return ppp_fsm_input(&ctx->pap.fsm, PPP_PAP, pkt);
}

static struct net_pkt *pap_config_info_add(struct ppp_fsm *fsm)
{
	uint8_t payload[] = { 5, 'b', 'l', 'a', 'n', 'k',
			      5, 'b', 'l', 'a', 'n', 'k' };
	struct net_pkt *pkt;

	pkt = net_pkt_alloc_with_buffer(ppp_fsm_iface(fsm), sizeof(payload),
					AF_UNSPEC, 0, PPP_BUF_ALLOC_TIMEOUT);
	if (!pkt) {
		return NULL;
	}

	(void)net_pkt_write(pkt, payload, sizeof(payload));

	return pkt;
}

static int pap_config_info_ack(struct ppp_fsm *fsm,
			       struct net_pkt *pkt,
			       uint16_t length)
{
	/*
	 * We only support one way negotiation for now, so move to ACK_SENT
	 * phase right away.
	 */
	if (fsm->state == PPP_REQUEST_SENT) {
		ppp_change_state(fsm, PPP_ACK_SENT);
	}

	return 0;
}

static void pap_lower_down(struct ppp_context *ctx)
{
	ppp_fsm_lower_down(&ctx->pap.fsm);
}

static void pap_lower_up(struct ppp_context *ctx)
{
	ppp_fsm_lower_up(&ctx->pap.fsm);
}

static void pap_open(struct ppp_context *ctx)
{
	ppp_fsm_open(&ctx->pap.fsm);
}

static void pap_close(struct ppp_context *ctx, const uint8_t *reason)
{
	ppp_fsm_close(&ctx->pap.fsm, reason);
}

static void pap_up(struct ppp_fsm *fsm)
{
	struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
					       pap.fsm);

	if (ctx->is_pap_up) {
		return;
	}

	ctx->is_pap_up = true;

	NET_DBG("[%s/%p] Current state %s (%d)", fsm->name, fsm,
		ppp_state_str(fsm->state), fsm->state);

	ppp_link_authenticated(ctx);
}

static void pap_down(struct ppp_fsm *fsm)
{
	struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
					       pap.fsm);

	if (!ctx->is_pap_up) {
		return;
	}

	ctx->is_pap_up = false;
}

static void pap_finished(struct ppp_fsm *fsm)
{
	struct ppp_context *ctx = CONTAINER_OF(fsm, struct ppp_context,
					       pap.fsm);

	if (!ctx->is_pap_open) {
		return;
	}

	ctx->is_pap_open = false;
}

static void pap_proto_reject(struct ppp_fsm *fsm)
{
	ppp_fsm_lower_down(fsm);
}

static void pap_init(struct ppp_context *ctx)
{
	NET_DBG("proto %s (0x%04x) fsm %p", ppp_proto2str(PPP_PAP), PPP_PAP,
		&ctx->pap.fsm);

	memset(&ctx->pap.fsm, 0, sizeof(ctx->pap.fsm));

	ppp_fsm_init(&ctx->pap.fsm, PPP_PAP);

	ppp_fsm_name_set(&ctx->pap.fsm, ppp_proto2str(PPP_PAP));

	ctx->pap.fsm.cb.up = pap_up;
	ctx->pap.fsm.cb.down = pap_down;
	ctx->pap.fsm.cb.finished = pap_finished;
	ctx->pap.fsm.cb.proto_reject = pap_proto_reject;
	ctx->pap.fsm.cb.config_info_add = pap_config_info_add;
	ctx->pap.fsm.cb.config_info_ack = pap_config_info_ack;
}

PPP_PROTOCOL_REGISTER(PAP, PPP_PAP,
		      pap_init, pap_handle,
		      pap_lower_up, pap_lower_down,
		      pap_open, pap_close);
