/* Copyright (C) 2021-2022 Mediatek Inc. */

#include <signal.h>
#include <sys/select.h>
#include <sys/wait.h>
#include "atenl.h"

static const char *progname;
bool atenl_enable;

void sig_handler(int signum)
{
	atenl_enable = false;
}

void atenl_init_signals()
{
	if (signal(SIGINT, sig_handler) == SIG_ERR)
		goto out;
	if (signal(SIGTERM, sig_handler) == SIG_ERR)
		goto out;
	if (signal(SIGABRT, sig_handler) == SIG_ERR)
		goto out;
	if (signal(SIGUSR1, sig_handler) == SIG_ERR)
		goto out;
	if (signal(SIGUSR2, sig_handler) == SIG_ERR)
		goto out;

	return;
out:
	perror("signal");
}

static int phy_lookup_idx(const char *name)
{
	char buf[128];
	FILE *f;
	size_t len;
	int ret;

	ret = snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name);
	if (snprintf_error(sizeof(buf), ret))
		return -1;

	f = fopen(buf, "r");
	if (!f)
		return -1;

	len = fread(buf, 1, sizeof(buf) - 1, f);
	fclose(f);

	if (!len)
		return -1;

	buf[len] = 0;
	return atoi(buf);
}

static int get_default_bridge_name(struct atenl *an)
{
	char buf[128];
	FILE *f;
	size_t len;
	int ret;

	ret = snprintf(buf, sizeof(buf), "/sbin/procd");
	if (snprintf_error(sizeof(buf), ret))
		return -1;

	f = fopen(buf, "r");

	/* This procd is openwrt only */
	if (f) {
		an->bridge_name = BRIDGE_NAME_OPENWRT;
		fclose(f);
	} else {
		an->bridge_name = BRIDGE_NAME_RDKB;
	}

	return 0;
}

static void usage(void)
{
	printf("Usage:\n");
	printf("  %s [-u] [-i phyX]\n", progname);
	printf("options:\n"
	       "  -h = show help text\n"
	       "  -i = phy name of driver interface, please use first phy for dbdc\n"
	       "  -u = use unicast to respond to HQADLL\n"
	       "  -b = specify your bridge name\n");
	printf("examples:\n"
	       "  %s -u -i phy0 -b br-lan\n", progname);

	exit(EXIT_FAILURE);
}

static void atenl_handler_run(struct atenl *an)
{
	int count, sock_eth = an->sock_eth;
	fd_set readfds;

	atenl_info("Start atenl HQA command handler\n");

	while (atenl_enable) {
		FD_ZERO(&readfds);
		FD_SET(sock_eth, &readfds);
		count = select(sock_eth + 1, &readfds, NULL, NULL, NULL);

		if (count < 0) {
			atenl_err("%s: select failed, %s\n", __func__, strerror(errno));
		} else if (count == 0) {
			usleep(1000);
		} else {
			if (!FD_ISSET(sock_eth, &readfds))
				continue;
			atenl_hqa_proc_cmd(an);
		}
	}

	atenl_dbg("HQA command handler end\n");
}

int main(int argc, char **argv)
{
	int opt, phy_idx, ret = 0;
	char *phy = "phy0", *cmd = NULL;
	struct atenl *an;

	progname = argv[0];

	an = calloc(1, sizeof(struct atenl));
	if (!an)
		return -ENOMEM;

	while(1) {
		opt = getopt(argc, argv, "hi:uc:b:");
		if (opt == -1)
			break;

		switch (opt) {
			case 'h':
				usage();
				goto out;
			case 'i':
				phy = optarg;
				break;
			case 'b':
				an->bridge_name = optarg;
				break;
			case 'u':
				an->unicast = true;
				printf("Opt: use unicast to send response\n");
				break;
			case 'c':
				cmd = optarg;
				break;
			default:
				atenl_err("Not supported option: %c\n", opt);
				goto out;
		}
	}

	phy_idx = phy_lookup_idx(phy);
	if (phy_idx < 0 || phy_idx > UCHAR_MAX) {
		atenl_err("Could not find phy '%s'\n", phy);
		goto out;
	}

	if (cmd) {
		atenl_eeprom_cmd_handler(an, phy_idx, cmd);
		goto out;
	}

	atenl_enable = true;
	atenl_init_signals();

	if (!an->bridge_name) {
		ret = get_default_bridge_name(an);
		if (ret) {
			atenl_err("Get default bridge name failed\n");
			goto out;
		}

		atenl_info("Bridge name is not specified, use default bridge name: %s\n", an->bridge_name);
	} else {
		atenl_info("Currently using bridge name: %s\n", an->bridge_name);
	}

	/* background ourself */
	if (!fork()) {
		ret = atenl_eeprom_init(an, phy_idx);
		if (ret)
			goto out;

		ret = atenl_eth_init(an);
		if (ret)
			goto out;

		atenl_handler_run(an);
	} else {
		usleep(800000);
	}

	ret = 0;
out:
	if (an->sock_eth)
		close(an->sock_eth);
	if (an->eeprom_fd || an->eeprom_data)
		atenl_eeprom_close(an);
	free(an);

	return ret;
}
