#include <errno.h>

#include <netlink/genl/genl.h>
#include <netlink/genl/family.h>
#include <netlink/genl/ctrl.h>
#include <netlink/msg.h>
#include <netlink/attr.h>

#include "nl80211.h"
#include "iw.h"

static int iw_conn(struct nl80211_state *state,
		   struct nl_msg *msg, int argc, char **argv,
		   enum id_input id)
{
	char *end;
	unsigned char bssid[6];
	bool need_key = false;
	int freq;
	int ret;

	if (argc < 1)
		return 1;

	/* SSID */
	NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
	argv++;
	argc--;

	/* freq */
	if (argc) {
		freq = strtoul(argv[0], &end, 10);
		if (*end == '\0') {
			NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
			argv++;
			argc--;
		}
	}

	/* bssid */
	if (argc) {
		if (mac_addr_a2n(bssid, argv[0]) == 0) {
			NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid);
			argv++;
			argc--;
		}
	}

	if (!argc)
		return 0;

	if (strcmp(*argv, "auth") == 0) {
		argv++;
		argc--;

		if (!argc)
			return 1;

		if (strcmp(argv[0], "open") == 0) {
			NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
			    NL80211_AUTHTYPE_OPEN_SYSTEM);
		} else if (strcmp(argv[0], "shared") == 0) {
			NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
			    NL80211_AUTHTYPE_SHARED_KEY);
			need_key = true;
		} else {
			return 1;
		}

		argv++;
		argc--;
	}

	if (need_key && !argc)
		return 1;

	if (argc && strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
		return 1;

	argv++;
	argc--;

	ret = parse_keys(msg, &argv, &argc);
	if (ret)
		return ret;

	if (!argc)
		return 0;

	if (!strcmp(*argv, "mfp:req"))
		NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_REQUIRED);
	else if (!strcmp(*argv, "mfp:opt"))
		NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_OPTIONAL);
	else if (!strcmp(*argv, "mfp:no"))
		NLA_PUT_U32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_NO);
	else
		return -EINVAL;

	return 0;

 nla_put_failure:
	return -ENOSPC;
}

static int disconnect(struct nl80211_state *state,
		      struct nl_msg *msg,
		      int argc, char **argv,
		      enum id_input id)
{
	return 0;
}
TOPLEVEL(disconnect, NULL,
	NL80211_CMD_DISCONNECT, 0, CIB_NETDEV, disconnect,
	"Disconnect from the current network.");

static int iw_connect(struct nl80211_state *state,
		      struct nl_msg *msg, int argc, char **argv,
		      enum id_input id)
{
	char **conn_argv, *dev = argv[0];
	static const __u32 cmds[] = {
		NL80211_CMD_CONNECT,
	};
	struct print_event_args printargs = { };
	int conn_argc, err;
	bool wait = false;
	int i;

	/* strip "wlan0 connect" */
	argc -= 2;
	argv += 2;

	/* check -w */
	if (argc && strcmp(argv[0], "-w") == 0) {
		wait = true;
		argc--;
		argv++;
	}

	err = __prepare_listen_events(state);
	if (err)
		return err;

	conn_argc = 3 + argc;
	conn_argv = calloc(conn_argc, sizeof(*conn_argv));
	if (!conn_argv)
		return -ENOMEM;

	conn_argv[0] = dev;
	conn_argv[1] = "connect";
	conn_argv[2] = "establish";
	for (i = 0; i < argc; i++)
		conn_argv[i + 3] = argv[i];
	err = handle_cmd(state, id, conn_argc, conn_argv);
	free(conn_argv);
	if (err)
		return err;

	if (!wait)
		return 0;

	/*
	 * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION
	 *
	 * This code has a bug:
	 *
	 * It is possible for a connect result message from another
	 * connect attempt to be processed here first, because we
	 * start listening to the multicast group before starting
	 * our own connect request, which may succeed but we get a
	 * fail message from a previous attempt that raced with us,
	 * or similar.
	 *
	 * The only proper way to fix this would be to listen to events
	 * before sending the command, and for the kernel to send the
	 * connect request or a cookie along with the event, so that you
	 * can match up whether the connect _you_ requested was finished
	 * or aborted.
	 *
	 * Alas, the kernel doesn't do that (yet).
	 */

	__do_listen_events(state,
			   ARRAY_SIZE(cmds), cmds,
			   ARRAY_SIZE(cmds), cmds,
			   &printargs);
	return 0;
}
TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [auth open|shared] [key 0:abcde d:1:6162636465] [mfp:req/opt/no]",
	0, 0, CIB_NETDEV, iw_connect,
	"Join the network with the given SSID (and frequency, BSSID).\n"
	"With -w, wait for the connect to finish or fail.");
HIDDEN(connect, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn);

static int iw_auth(struct nl80211_state *state,
		   struct nl_msg *msg, int argc, char **argv,
		   enum id_input id)
{
	char *end;
	unsigned char bssid[6];
	int freq;
	bool need_key = false;

	if (argc < 4)
		return 1;

	/* SSID */
	NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]);
	argv++;
	argc--;

	/* bssid */
	if (mac_addr_a2n(bssid, argv[0]) == 0) {
		NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid);
		argv++;
		argc--;
	} else {
		return 1;
	}

	/* FIXME */
	if (strcmp(argv[0], "open") == 0) {
		NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
			    NL80211_AUTHTYPE_OPEN_SYSTEM);
	} else if (strcmp(argv[0], "shared") == 0) {
		NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
			    NL80211_AUTHTYPE_SHARED_KEY);
		need_key = true;
	} else {
		return 1;
	}
	argv++;
	argc--;

	freq = strtoul(argv[0], &end, 10);
	if (*end == '\0') {
		NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
		argv++;
		argc--;
	} else {
		return 1;
	}

	if (!argc && need_key)
		return 1;
	if (argc && !need_key)
		return 1;
	if (!argc)
		return 0;

	if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0)
		return 1;

	argv++;
	argc--;

	return parse_keys(msg, &argv, &argc);
 nla_put_failure:
	return -ENOSPC;
}

TOPLEVEL(auth, "<SSID> <bssid> <type:open|shared> <freq in MHz> [key 0:abcde d:1:6162636465]",
	 NL80211_CMD_AUTHENTICATE, 0, CIB_NETDEV, iw_auth,
	 "Authenticate with the given network.\n");
