/* (C) 2020 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <stdint.h>
#include <string.h>
#include <errno.h>

#include <osmocom/core/talloc.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/exec.h>

#include "rspro_util.h"
#include "client.h"
#include "debug.h"

#define S(x)	(1 << (x))

/***********************************************************************/

/* build the (additional) environment for executing a script */
static char **build_script_env(struct bankd_client *bc, const char *cause)
{
	char **env = talloc_zero_size(bc, 256*sizeof(char *));
	int rc, i = 0;

	if (!env)
		return NULL;

	env[i++] = talloc_asprintf(env, "REMSIM_CLIENT_VERSION=%s", VERSION);

	env[i++] = talloc_asprintf(env, "REMSIM_SERVER_ADDR=%s:%u",
				   bc->srv_conn.server_host, bc->srv_conn.server_port);
	env[i++] = talloc_asprintf(env, "REMSIM_SERVER_STATE=%s",
				   osmo_fsm_inst_state_name(bc->srv_conn.fi));

	env[i++] = talloc_asprintf(env, "REMSIM_BANKD_ADDR=%s:%u",
				   bc->bankd_conn.server_host, bc->bankd_conn.server_port);
	env[i++] = talloc_asprintf(env, "REMSIM_BANKD_STATE=%s",
				   osmo_fsm_inst_state_name(bc->bankd_conn.fi));


	if (bc->srv_conn.clslot) {
		env[i++] = talloc_asprintf(env, "REMSIM_CLIENT_SLOT=%lu:%lu",
					   bc->srv_conn.clslot->clientId,
					   bc->srv_conn.clslot->slotNr);
	}
	env[i++] = talloc_asprintf(env, "REMSIM_BANKD_SLOT=%u:%u",
				   bc->bankd_slot.bank_id, bc->bankd_slot.slot_nr);

	env[i++] = talloc_asprintf(env, "REMSIM_SIM_VCC=%u", bc->last_status.flags.vcc_present);
	env[i++] = talloc_asprintf(env, "REMSIM_SIM_RST=%u", bc->last_status.flags.reset_active);
	env[i++] = talloc_asprintf(env, "REMSIM_SIM_CLK=%u", bc->last_status.flags.clk_active);

	env[i++] = talloc_asprintf(env, "REMSIM_CAUSE=%s", cause);

	/* ask frontend to append any frontend-specific additional environment vars */
	rc = frontend_append_script_env(bc, env, i, 256-i-1);
	if (rc > 0)
		i = rc;

	/* terminate last entry */
	env[i++] = NULL;
	return env;
}

static int call_script(struct bankd_client *bc, const char *cause)
{
	char **env, *cmd;
	int rc;

	if (!bc->cfg->event_script)
		return 0;

	env = build_script_env(bc, cause);
	if (!env)
		return -ENOMEM;

	cmd = talloc_asprintf(env, "%s %s", bc->cfg->event_script, cause);
	if (!cmd) {
		talloc_free(env);
		return -ENOMEM;
	}

	rc = osmo_system_nowait(cmd, osmo_environment_whitelist, env);
	talloc_free(env);

	return rc;
}


/***********************************************************************/


enum main_fsm_state {
	MF_ST_INIT,
	MF_ST_UNCONFIGURED,	/* waiting for configuration from server */
	MF_ST_WAIT_BANKD,	/* configured; waiting for bankd conn */
	MF_ST_OPERATIONAL,	/* fully operational (configured + bankd conn live */
};

static const struct value_string main_fsm_event_names[] = {
	OSMO_VALUE_STRING(MF_E_SRVC_CONNECTED),
	OSMO_VALUE_STRING(MF_E_SRVC_LOST),
	OSMO_VALUE_STRING(MF_E_SRVC_CONFIG_BANK),
	OSMO_VALUE_STRING(MF_E_SRVC_RESET_REQ),
	OSMO_VALUE_STRING(MF_E_BANKD_CONNECTED),
	OSMO_VALUE_STRING(MF_E_BANKD_LOST),
	OSMO_VALUE_STRING(MF_E_BANKD_TPDU),
	OSMO_VALUE_STRING(MF_E_BANKD_ATR),
	OSMO_VALUE_STRING(MF_E_BANKD_SLOT_STATUS),
	OSMO_VALUE_STRING(MF_E_MDM_STATUS_IND),
	OSMO_VALUE_STRING(MF_E_MDM_PTS_IND),
	OSMO_VALUE_STRING(MF_E_MDM_TPDU),
	{ 0, NULL }
};

static void main_st_operational(struct osmo_fsm_inst *fi, uint32_t event, void *data);

static void main_st_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;

	switch (event) {
	case MF_E_SRVC_CONNECTED:
		osmo_fsm_inst_state_chg(fi, MF_ST_UNCONFIGURED, 0, 0);
		call_script(bc, "event-server-connect");
		break;
	default:
		OSMO_ASSERT(0);
	}
}

static void main_st_unconfigured_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;
	/* we might be called from a 'higher' state such as operational; clean up */
	osmo_fsm_inst_dispatch(bc->bankd_conn.fi, SRVC_E_DISCONNECT, NULL);
}

static void main_st_unconfigured(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	switch (event) {
	case MF_E_SRVC_CONFIG_BANK:
		/* same treatment as below */
		main_st_operational(fi, event, data);
		break;
	default:
		OSMO_ASSERT(0);
	}
}

static void main_st_wait_bankd(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;

	switch (event) {
	case MF_E_SRVC_CONFIG_BANK:
		/* same treatment as below */
		main_st_operational(fi, event, data);
		break;
	case MF_E_BANKD_CONNECTED:
		osmo_fsm_inst_state_chg(fi, MF_ST_OPERATIONAL, 0, 0);
		call_script(bc, "event-bankd-connect");
		break;
	default:
		OSMO_ASSERT(0);
	}
}

static void main_st_operational_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;

	/* Simulate card-insert to modem */
	frontend_request_card_insert(bc);
	call_script(bc, "request-card-insert");

	/* Select remote (forwarded) SIM */
	frontend_request_sim_remote(bc);
	call_script(bc, "request-sim-remote");

	/* Set the ATR */
	frontend_handle_set_atr(bc, bc->cfg->atr.data, bc->cfg->atr.len);

	/* Reset the modem */
	frontend_request_modem_reset(bc);
	call_script(bc, "request-modem-reset");
}

static void main_st_operational_onleave(struct osmo_fsm_inst *fi, uint32_t next_state)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;

	/* Simulate a card-remval to modem */
	frontend_request_card_remove(bc);
	call_script(bc, "request-card-remove");

	/* Select local SIM */
	frontend_request_sim_local(bc);
	call_script(bc, "request-sim-local");

	/* Reset the modem */
	frontend_request_modem_reset(bc);
	call_script(bc, "request-modem-reset");
}

static void main_st_operational(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct bankd_client *bc = (struct bankd_client *) fi->priv;
	struct frontend_phys_status *pstatus = NULL;
	struct frontend_pts *pts = NULL;
	struct frontend_tpdu *tpdu = NULL;
	RsproPDU_t *pdu_rx = NULL;
	RsproPDU_t *resp;
	BankSlot_t bslot;

	switch (event) {
	case MF_E_BANKD_LOST:
		osmo_fsm_inst_state_chg(fi, MF_ST_WAIT_BANKD, 0, 0);
		break;
	case MF_E_SRVC_CONFIG_BANK:
		pdu_rx = data;
		OSMO_ASSERT(pdu_rx);
		OSMO_ASSERT(pdu_rx->msg.present == RsproPDUchoice_PR_configClientBankReq);
		/* store/set the bankd ip/port as instructed by the server */
		osmo_talloc_replace_string(bc, &bc->bankd_conn.server_host,
					   rspro_IpAddr2str(&pdu_rx->msg.choice.configClientBankReq.bankd.ip));
		bc->bankd_conn.server_port = pdu_rx->msg.choice.configClientBankReq.bankd.port;
		rspro2bank_slot(&bc->bankd_slot, &pdu_rx->msg.choice.configClientBankReq.bankSlot);
		/* bankd port 0 is a magic value to indicate "no bankd" */
		if (bc->bankd_conn.server_port == 0)
			osmo_fsm_inst_state_chg(fi, MF_ST_UNCONFIGURED, 0, 0);
		else {
			osmo_fsm_inst_state_chg(fi, MF_ST_WAIT_BANKD, 0, 0);
			/* TODO: do we need to disconnect before? */
			osmo_fsm_inst_dispatch(bc->bankd_conn.fi, SRVC_E_ESTABLISH, NULL);
		}
		/* send response to server */
		resp = rspro_gen_ConfigClientBankRes(ResultCode_ok);
		server_conn_send_rspro(&bc->srv_conn, resp);
		call_script(bc, "event-config-bankd");
		break;
	case MF_E_BANKD_TPDU:
		pdu_rx = data;
		OSMO_ASSERT(pdu_rx);
		OSMO_ASSERT(pdu_rx->msg.present == RsproPDUchoice_PR_tpduCardToModem);
		/* forward to modem/cardem (via API) */
		frontend_handle_card2modem(bc, pdu_rx->msg.choice.tpduCardToModem.data.buf,
					   pdu_rx->msg.choice.tpduCardToModem.data.size);
		/* response happens indirectly via tpduModemToCard */
		break;
	case MF_E_BANKD_ATR:
		pdu_rx = data;
		OSMO_ASSERT(pdu_rx);
		OSMO_ASSERT(pdu_rx->msg.present == RsproPDUchoice_PR_setAtrReq);
		/* forward to modem/cardem (via API) */
		frontend_handle_set_atr(bc, pdu_rx->msg.choice.setAtrReq.atr.buf,
					pdu_rx->msg.choice.setAtrReq.atr.size);
		/* send response to bankd */
		resp = rspro_gen_SetAtrRes(ResultCode_ok);
		server_conn_send_rspro(&bc->bankd_conn, resp);
		break;
	case MF_E_BANKD_SLOT_STATUS:
		pdu_rx = data;
		OSMO_ASSERT(pdu_rx);
		OSMO_ASSERT(pdu_rx->msg.present == RsproPDUchoice_PR_bankSlotStatusInd);
		/* forward to modem/cardem (via API) */
		frontend_handle_slot_status(bc, &pdu_rx->msg.choice.bankSlotStatusInd.slotPhysStatus);
		break;
	case MF_E_MDM_STATUS_IND:
		pstatus = data;
		OSMO_ASSERT(pstatus);
		/* forward to bankd */
		bank_slot2rspro(&bslot, &bc->bankd_slot);
		resp = rspro_gen_ClientSlotStatusInd(bc->srv_conn.clslot, &bslot,
						     pstatus->flags.reset_active,
						     pstatus->flags.vcc_present,
						     pstatus->flags.clk_active,
						     pstatus->flags.card_present);
		server_conn_send_rspro(&bc->bankd_conn, resp);
		if (!memcmp(&bc->last_status.flags, &pstatus->flags, sizeof(pstatus->flags)))
			call_script(bc, "event-modem-status");
		bc->last_status = *pstatus;
		break;
	case MF_E_MDM_PTS_IND:
		pts = data;
		OSMO_ASSERT(pts);
		/* forward to bankd? */
		break;
	case MF_E_MDM_TPDU:
		tpdu = data;
		OSMO_ASSERT(tpdu);
		/* forward to bankd */
		bank_slot2rspro(&bslot, &bc->bankd_slot);
		resp = rspro_gen_TpduModem2Card(bc->srv_conn.clslot, &bslot, tpdu->buf, tpdu->len);
		server_conn_send_rspro(&bc->bankd_conn, resp);
		break;
	default:
		OSMO_ASSERT(0);
	}
}

static void main_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	switch (event) {
	case MF_E_SRVC_LOST:
		/* should we do anything? The SRVC fsm will take care of reconnect, and we
		 * can continue to talk to the bankd without any trouble... */
		break;
	case MF_E_SRVC_RESET_REQ:
		osmo_fsm_inst_state_chg(fi, MF_ST_UNCONFIGURED, 0, 0);
		break;
	default:
		OSMO_ASSERT(0);
	}
}


static const struct osmo_fsm_state main_fsm_states[] = {
	[MF_ST_INIT] = {
		.name = "INIT",
		.in_event_mask = S(MF_E_SRVC_CONNECTED),
		.out_state_mask = S(MF_ST_UNCONFIGURED),
		.action = main_st_init,
	},
	[MF_ST_UNCONFIGURED] = {
		.name = "UNCONFIGURED",
		.in_event_mask = S(MF_E_SRVC_CONFIG_BANK),
		.out_state_mask = S(MF_ST_INIT) | S(MF_ST_WAIT_BANKD),
		.action = main_st_unconfigured,
		.onenter = main_st_unconfigured_onenter,
	},
	[MF_ST_WAIT_BANKD] = {
		.name = "WAIT_BANKD",
		.in_event_mask = S(MF_E_SRVC_CONFIG_BANK) | S(MF_E_BANKD_CONNECTED),
		.out_state_mask = S(MF_ST_INIT) | S(MF_ST_UNCONFIGURED) | S(MF_ST_OPERATIONAL),
		.action = main_st_wait_bankd,
	},
	[MF_ST_OPERATIONAL] = {
		.name = "OPERATIONAL",
		.in_event_mask = S(MF_E_SRVC_CONFIG_BANK) |
				 S(MF_E_BANKD_LOST) |
				 S(MF_E_BANKD_TPDU) |
				 S(MF_E_BANKD_ATR) |
				 S(MF_E_BANKD_SLOT_STATUS) |
				 S(MF_E_MDM_STATUS_IND) |
				 S(MF_E_MDM_PTS_IND) |
				 S(MF_E_MDM_TPDU),
		.out_state_mask = S(MF_ST_INIT) | S(MF_ST_UNCONFIGURED) | S(MF_ST_WAIT_BANKD),
		.action = main_st_operational,
		.onenter = main_st_operational_onenter,
		.onleave = main_st_operational_onleave,
	},
};

static struct osmo_fsm client_main_fsm = {
	.name = "CLIENT_MAIN",
	.states = main_fsm_states,
	.num_states = ARRAY_SIZE(main_fsm_states),
	.allstate_event_mask = S(MF_E_SRVC_LOST) | S(MF_E_SRVC_RESET_REQ),
	.allstate_action = main_allstate_action,
	.log_subsys = DMAIN,
	.event_names = main_fsm_event_names,
};

struct osmo_fsm_inst *main_fsm_alloc(void *ctx, struct bankd_client *bc)
{
	return osmo_fsm_inst_alloc(&client_main_fsm, ctx, bc, LOGL_DEBUG, "main");
}

static __attribute((constructor)) void on_dso_load_main_fsm(void)
{
	OSMO_ASSERT(osmo_fsm_register(&client_main_fsm) == 0);
}
