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

#include "supp_events.h"

#include "includes.h"
#include "common.h"
#include "common/ieee802_11_defs.h"
#include "wpa_supplicant_i.h"

#ifdef CONFIG_AP
#include "ap/sta_info.h"
#include "ap/ieee802_11.h"
#include "ap/hostapd.h"
#endif /* CONFIG_AP */

#include <zephyr/net/wifi_mgmt.h>

/* Re-defines MAC2STR with address of the element */
#define MACADDR2STR(a) &(a)[0], &(a)[1], &(a)[2], &(a)[3], &(a)[4], &(a)[5]

static const struct wpa_supp_event_info {
	const char *event_str;
	enum supplicant_event_num event;
} wpa_supp_event_info[] = {
	{ "CTRL-EVENT-CONNECTED", SUPPLICANT_EVENT_CONNECTED },
	{ "CTRL-EVENT-DISCONNECTED", SUPPLICANT_EVENT_DISCONNECTED },
	{ "CTRL-EVENT-ASSOC-REJECT", SUPPLICANT_EVENT_ASSOC_REJECT },
	{ "CTRL-EVENT-AUTH-REJECT", SUPPLICANT_EVENT_AUTH_REJECT },
	{ "CTRL-EVENT-SSID-TEMP-DISABLED", SUPPLICANT_EVENT_SSID_TEMP_DISABLED },
	{ "CTRL-EVENT-SSID-REENABLED", SUPPLICANT_EVENT_SSID_REENABLED },
	{ "CTRL-EVENT-BSS-ADDED", SUPPLICANT_EVENT_BSS_ADDED },
	{ "CTRL-EVENT-BSS-REMOVED", SUPPLICANT_EVENT_BSS_REMOVED },
	{ "CTRL-EVENT-TERMINATING", SUPPLICANT_EVENT_TERMINATING },
	{ "CTRL-EVENT-SCAN-STARTED", SUPPLICANT_EVENT_SCAN_STARTED },
	{ "CTRL-EVENT-SCAN-FAILED", SUPPLICANT_EVENT_SCAN_FAILED },
	{ "CTRL-EVENT-NETWORK-NOT-FOUND", SUPPLICANT_EVENT_NETWORK_NOT_FOUND },
	{ "CTRL-EVENT-NETWORK-ADDED", SUPPLICANT_EVENT_NETWORK_ADDED },
	{ "CTRL-EVENT-NETWORK-REMOVED", SUPPLICANT_EVENT_NETWORK_REMOVED },
	{ "CTRL-EVENT-DSCP-POLICY", SUPPLICANT_EVENT_DSCP_POLICY },
};

static void copy_mac_addr(const unsigned int *src, uint8_t *dst)
{
	int i;

	for (i = 0; i < ETH_ALEN; i++) {
		dst[i] = src[i];
	}
}

static enum wifi_conn_status wpas_to_wifi_mgmt_conn_status(int status)
{
	switch (status) {
	case WLAN_STATUS_SUCCESS:
		return WIFI_STATUS_CONN_SUCCESS;
	case WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT:
		return WIFI_STATUS_CONN_WRONG_PASSWORD;
	/* Handle non-supplicant errors */
	case -ETIMEDOUT:
		return WIFI_STATUS_CONN_TIMEOUT;
	default:
		return WIFI_STATUS_CONN_FAIL;
	}
}

static enum wifi_disconn_reason wpas_to_wifi_mgmt_diconn_status(int status)
{
	switch (status) {
	case WLAN_REASON_DEAUTH_LEAVING:
		return WIFI_REASON_DISCONN_AP_LEAVING;
	case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
		return WIFI_REASON_DISCONN_INACTIVITY;
	case WLAN_REASON_UNSPECIFIED:
	/* fall through */
	default:
		return WIFI_REASON_DISCONN_UNSPECIFIED;
	}
}

static int supplicant_process_status(struct supplicant_int_event_data *event_data,
				     char *supplicant_status)
{
	int ret = 1; /* For cases where parsing is not being done*/
	int i;
	union supplicant_event_data *data;
	unsigned int tmp_mac_addr[ETH_ALEN];
	unsigned int event_prefix_len;
	char *event_no_prefix;
	struct wpa_supp_event_info event_info;

	data = (union supplicant_event_data *)event_data->data;

	for (i = 0; i < ARRAY_SIZE(wpa_supp_event_info); i++) {
		if (strncmp(supplicant_status, wpa_supp_event_info[i].event_str,
		    strlen(wpa_supp_event_info[i].event_str)) == 0) {
			event_info = wpa_supp_event_info[i];
			break;
		}
	}

	if (i >= ARRAY_SIZE(wpa_supp_event_info)) {
		/* This is not a bug but rather implementation gap (intentional or not) */
		wpa_printf(MSG_DEBUG, "Event not supported: %s", supplicant_status);
		return -ENOTSUP;
	}

	/* Skip the event prefix and a space */
	event_prefix_len = strlen(event_info.event_str) + 1;
	event_no_prefix = supplicant_status + event_prefix_len;
	event_data->event = event_info.event;

	switch (event_data->event) {
	case SUPPLICANT_EVENT_CONNECTED:
		ret = sscanf(event_no_prefix, "- Connection to"
			MACSTR, MACADDR2STR(tmp_mac_addr));
		event_data->data_len = sizeof(data->connected);
		copy_mac_addr(tmp_mac_addr, data->connected.bssid);
		break;
	case SUPPLICANT_EVENT_DISCONNECTED:
		ret = sscanf(event_no_prefix,
			MACSTR" reason=%d", MACADDR2STR(tmp_mac_addr),
			&data->disconnected.reason_code);
		event_data->data_len = sizeof(data->disconnected);
		copy_mac_addr(tmp_mac_addr, data->disconnected.bssid);
		break;
	case SUPPLICANT_EVENT_ASSOC_REJECT:
		/* TODO */
		break;
	case SUPPLICANT_EVENT_AUTH_REJECT:
		ret = sscanf(event_no_prefix, MACSTR
			" auth_type=%u auth_transaction=%u status_code=%u",
			MACADDR2STR(tmp_mac_addr),
			&data->auth_reject.auth_type,
			&data->auth_reject.auth_transaction,
			&data->auth_reject.status_code);
		event_data->data_len = sizeof(data->auth_reject);
		copy_mac_addr(tmp_mac_addr, data->auth_reject.bssid);
		break;
	case SUPPLICANT_EVENT_SSID_TEMP_DISABLED:
		ret = sscanf(event_no_prefix,
			"id=%d ssid=%s auth_failures=%u duration=%d reason=%s",
			&data->temp_disabled.id, data->temp_disabled.ssid,
			&data->temp_disabled.auth_failures,
			&data->temp_disabled.duration,
			data->temp_disabled.reason_code);
		event_data->data_len = sizeof(data->temp_disabled);
		break;
	case SUPPLICANT_EVENT_SSID_REENABLED:
		ret = sscanf(event_no_prefix,
			"id=%d ssid=%s", &data->reenabled.id,
			data->reenabled.ssid);
		event_data->data_len = sizeof(data->reenabled);
		break;
	case SUPPLICANT_EVENT_BSS_ADDED:
		ret = sscanf(event_no_prefix, "%u "MACSTR,
			&data->bss_added.id,
			MACADDR2STR(tmp_mac_addr));
		copy_mac_addr(tmp_mac_addr, data->bss_added.bssid);
		event_data->data_len = sizeof(data->bss_added);
		break;
	case SUPPLICANT_EVENT_BSS_REMOVED:
		ret = sscanf(event_no_prefix,
			"%u "MACSTR,
			&data->bss_removed.id,
			MACADDR2STR(tmp_mac_addr));
		event_data->data_len = sizeof(data->bss_removed);
		copy_mac_addr(tmp_mac_addr, data->bss_removed.bssid);
		break;
	case SUPPLICANT_EVENT_TERMINATING:
	case SUPPLICANT_EVENT_SCAN_STARTED:
	case SUPPLICANT_EVENT_SCAN_FAILED:
	case SUPPLICANT_EVENT_NETWORK_NOT_FOUND:
	case SUPPLICANT_EVENT_NETWORK_ADDED:
	case SUPPLICANT_EVENT_NETWORK_REMOVED:
		strncpy(data->supplicant_event_str, event_info.event_str,
			sizeof(data->supplicant_event_str) - 1);
		event_data->data_len = strlen(data->supplicant_event_str) + 1;
	case SUPPLICANT_EVENT_DSCP_POLICY:
		/* TODO */
		break;
	default:
		break;
	}

	if (ret <= 0) {
		wpa_printf(MSG_ERROR, "%s Parse failed: %s",
			   event_info.event_str, strerror(errno));
	}

	return ret;
}

int supplicant_send_wifi_mgmt_conn_event(void *ctx, int status_code)
{
	struct wpa_supplicant *wpa_s = ctx;
	int status = wpas_to_wifi_mgmt_conn_status(status_code);
	enum net_event_wifi_cmd event;

	if (!wpa_s || !wpa_s->current_ssid) {
		return -EINVAL;
	}

	if (wpa_s->current_ssid->mode == WPAS_MODE_AP) {
		event = NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT;
	} else {
		event = NET_EVENT_WIFI_CMD_CONNECT_RESULT;
	}

	return supplicant_send_wifi_mgmt_event(wpa_s->ifname,
					       event,
					       (void *)&status,
					       sizeof(int));
}

int supplicant_send_wifi_mgmt_disc_event(void *ctx, int reason_code)
{
	struct wpa_supplicant *wpa_s = ctx;
	int status = wpas_to_wifi_mgmt_diconn_status(reason_code);
	enum net_event_wifi_cmd event;

	if (!wpa_s || !wpa_s->current_ssid) {
		return -EINVAL;
	}

	if (wpa_s->wpa_state >= WPA_COMPLETED) {
		if (wpa_s->current_ssid->mode == WPAS_MODE_AP) {
			event = NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT;
		} else {
			event = NET_EVENT_WIFI_CMD_DISCONNECT_RESULT;
		}
	} else {
		if (wpa_s->current_ssid->mode == WPAS_MODE_AP) {
			event = NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT;
		} else {
			event = NET_EVENT_WIFI_CMD_CONNECT_RESULT;
		}
	}

	return supplicant_send_wifi_mgmt_event(wpa_s->ifname,
					       event,
					       (void *)&status,
					       sizeof(int));
}

#ifdef CONFIG_AP
static enum wifi_link_mode get_sta_link_mode(struct wpa_supplicant *wpa_s, struct sta_info *sta)
{
	if (sta->flags & WLAN_STA_HE) {
		return WIFI_6;
	} else if (sta->flags & WLAN_STA_VHT) {
		return WIFI_5;
	} else if (sta->flags & WLAN_STA_HT) {
		return WIFI_4;
	} else if (sta->flags & WLAN_STA_NONERP) {
		return WIFI_1;
	} else if (wpa_s->assoc_freq > 4000) {
		return WIFI_2;
	} else if (wpa_s->assoc_freq > 2000) {
		return WIFI_3;
	} else {
		return WIFI_LINK_MODE_UNKNOWN;
	}
}

static bool is_twt_capable(struct wpa_supplicant *wpa_s, struct sta_info *sta)
{
	return hostapd_get_he_twt_responder(wpa_s->ap_iface->bss[0], IEEE80211_MODE_AP);
}

int supplicant_send_wifi_mgmt_ap_status(void *ctx,
					enum net_event_wifi_cmd event,
					enum wifi_ap_status ap_status)
{
	struct wpa_supplicant *wpa_s = ctx;
	int status = ap_status;

	return supplicant_send_wifi_mgmt_event(wpa_s->ifname,
					       event,
					       (void *)&status,
					       sizeof(int));
}

int supplicant_send_wifi_mgmt_ap_sta_event(void *ctx,
					   enum net_event_wifi_cmd event,
					   void *data)
{
	struct sta_info *sta = data;
	struct wpa_supplicant *wpa_s = ctx;
	struct wifi_ap_sta_info sta_info = { 0 };

	if (!wpa_s || !sta) {
		return -EINVAL;
	}

	memcpy(sta_info.mac, sta->addr, sizeof(sta_info.mac));

	if (event == NET_EVENT_WIFI_CMD_AP_STA_CONNECTED) {
		sta_info.link_mode = get_sta_link_mode(wpa_s, sta);
		sta_info.twt_capable = is_twt_capable(wpa_s, sta);
	}

	return supplicant_send_wifi_mgmt_event(wpa_s->ifname,
					       event,
					       (void *)&sta_info,
					       sizeof(sta_info));
}
#endif /* CONFIG_AP */

int supplicant_send_wifi_mgmt_event(const char *ifname, enum net_event_wifi_cmd event,
				    void *supplicant_status, size_t len)
{
	struct net_if *iface = net_if_get_by_index(net_if_get_by_name(ifname));
	union supplicant_event_data data;
	struct supplicant_int_event_data event_data;

	if (!iface) {
		wpa_printf(MSG_ERROR, "Could not find iface for %s", ifname);
		return -ENODEV;
	}

	switch (event) {
	case NET_EVENT_WIFI_CMD_CONNECT_RESULT:
		wifi_mgmt_raise_connect_result_event(
			iface,
			*(int *)supplicant_status);
		break;
	case NET_EVENT_WIFI_CMD_DISCONNECT_RESULT:
		wifi_mgmt_raise_disconnect_result_event(
			iface,
			*(int *)supplicant_status);
		break;
#ifdef CONFIG_AP
	case NET_EVENT_WIFI_CMD_AP_ENABLE_RESULT:
		wifi_mgmt_raise_ap_enable_result_event(iface,
						       *(int *)supplicant_status);
		break;
	case NET_EVENT_WIFI_CMD_AP_DISABLE_RESULT:
		wifi_mgmt_raise_ap_disable_result_event(iface,
							*(int *)supplicant_status);
		break;
	case NET_EVENT_WIFI_CMD_AP_STA_CONNECTED:
		wifi_mgmt_raise_ap_sta_connected_event(iface,
				(struct wifi_ap_sta_info *)supplicant_status);
		break;
	case NET_EVENT_WIFI_CMD_AP_STA_DISCONNECTED:
		wifi_mgmt_raise_ap_sta_disconnected_event(iface,
				(struct wifi_ap_sta_info *)supplicant_status);
		break;
#endif /* CONFIG_AP */
	case NET_EVENT_SUPPLICANT_CMD_INT_EVENT:
		event_data.data = &data;
		if (supplicant_process_status(&event_data, (char *)supplicant_status) > 0) {
			net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_INT_EVENT,
						iface, &event_data, sizeof(event_data));
		}
		break;
	default:
		wpa_printf(MSG_ERROR, "Unsupported event %d", event);
		return -EINVAL;
	}

	return 0;
}

int supplicant_generate_state_event(const char *ifname,
				    enum net_event_supplicant_cmd event,
				    int status)
{
	struct net_if *iface;

	iface = net_if_get_by_index(net_if_get_by_name(ifname));
	if (!iface) {
		wpa_printf(MSG_ERROR, "Could not find iface for %s", ifname);
		return -ENODEV;
	}

	switch (event) {
	case NET_EVENT_SUPPLICANT_CMD_READY:
		net_mgmt_event_notify(NET_EVENT_SUPPLICANT_READY, iface);
		break;
	case NET_EVENT_SUPPLICANT_CMD_NOT_READY:
		net_mgmt_event_notify(NET_EVENT_SUPPLICANT_NOT_READY, iface);
		break;
	case NET_EVENT_SUPPLICANT_CMD_IFACE_ADDED:
		net_mgmt_event_notify(NET_EVENT_SUPPLICANT_IFACE_ADDED, iface);
		break;
	case NET_EVENT_SUPPLICANT_CMD_IFACE_REMOVING:
		net_mgmt_event_notify(NET_EVENT_SUPPLICANT_IFACE_REMOVING, iface);
		break;
	case NET_EVENT_SUPPLICANT_CMD_IFACE_REMOVED:
		net_mgmt_event_notify_with_info(NET_EVENT_SUPPLICANT_IFACE_REMOVED,
						iface, &status, sizeof(status));
		break;
	default:
		wpa_printf(MSG_ERROR, "Unsupported event %d", event);
		return -EINVAL;
	}

	return 0;
}
