/* (C) 2017 by sysmocom s.f.m.c. GmbH
 * All Rights Reserved
 *
 * Author: Philipp Maier
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/fsm.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/a_reset.h>

#define RESET_RESEND_INTERVAL 2	/* sec */
#define RESET_RESEND_TIMER_NO 1234	/* FIXME: dig out the real timer number */
#define BAD_CONNECTION_THRESOLD 3	/* connection failures */

enum fsm_states {
	ST_DISC,		/* Disconnected from remote end */
	ST_CONN,		/* We have a confirmed connection */
};

enum fsm_evt {
	EV_RESET_ACK,		/* got reset acknowlegement from remote end */
	EV_N_DISCONNECT,	/* lost a connection */
	EV_N_CONNECT,		/* made a successful connection */
};

/* Disconnected state */
static void fsm_disc_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct a_reset_ctx *reset = (struct a_reset_ctx *)data;
	OSMO_ASSERT(reset);
	OSMO_ASSERT(reset->fsm);
	LOGPFSML(reset->fsm, LOGL_NOTICE, "SIGTRAN connection succeded.\n");

	reset->conn_loss_counter = 0;
	osmo_fsm_inst_state_chg(fi, ST_CONN, 0, 0);
}

/* Connected state */
static void fsm_conn_cb(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct a_reset_ctx *reset = (struct a_reset_ctx *)data;
	OSMO_ASSERT(reset);

	switch (event) {
	case EV_N_DISCONNECT:
		if (reset->conn_loss_counter >= BAD_CONNECTION_THRESOLD) {
			LOGPFSML(reset->fsm, LOGL_NOTICE, "SIGTRAN connection down, reconnecting...\n");
			osmo_fsm_inst_state_chg(fi, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
		} else
			reset->conn_loss_counter++;
		break;
	case EV_N_CONNECT:
		reset->conn_loss_counter = 0;
		break;
	}
}

/* Timer callback to retransmit the reset signal */
static int fsm_reset_ack_timeout_cb(struct osmo_fsm_inst *fi)
{
	struct a_reset_ctx *reset = (struct a_reset_ctx *)fi->priv;
	OSMO_ASSERT(reset->fsm);

	LOGPFSML(reset->fsm, LOGL_NOTICE, "(re)sending BSSMAP RESET message...\n");

	reset->cb(reset->priv);

	osmo_fsm_inst_state_chg(fi, ST_DISC, RESET_RESEND_INTERVAL, RESET_RESEND_TIMER_NO);
	return 0;
}

static struct osmo_fsm_state fsm_states[] = {
	[ST_DISC] = {
		     .in_event_mask = (1 << EV_RESET_ACK),
		     .out_state_mask = (1 << ST_DISC) | (1 << ST_CONN),
		     .name = "DISC",
		     .action = fsm_disc_cb,
		     },
	[ST_CONN] = {
		     .in_event_mask = (1 << EV_N_DISCONNECT) | (1 << EV_N_CONNECT),
		     .out_state_mask = (1 << ST_DISC) | (1 << ST_CONN),
		     .name = "CONN",
		     .action = fsm_conn_cb,
		     },
};

/* State machine definition */
static struct osmo_fsm fsm = {
	.name = "A-RESET",
	.states = fsm_states,
	.num_states = ARRAY_SIZE(fsm_states),
	.log_subsys = DMSC,
	.timer_cb = fsm_reset_ack_timeout_cb,
};

/* Create and start state machine which handles the reset/reset-ack procedure */
struct a_reset_ctx *a_reset_alloc(const void *ctx, const char *name, void *cb, void *priv,
				  bool already_connected)
{
	OSMO_ASSERT(name);

	struct a_reset_ctx *reset;

	/* Register the fsm description (if not already done) */
	if (osmo_fsm_find_by_name(fsm.name) != &fsm)
		osmo_fsm_register(&fsm);

	/* Allocate and configure a new fsm instance */
	reset = talloc_zero(ctx, struct a_reset_ctx);
	OSMO_ASSERT(reset);
	reset->priv = priv;
	reset->cb = cb;
	reset->conn_loss_counter = 0;
	reset->fsm = osmo_fsm_inst_alloc(&fsm, NULL, NULL, LOGL_DEBUG, name);
	OSMO_ASSERT(reset->fsm);
	reset->fsm->priv = reset;

	if (already_connected)
		osmo_fsm_inst_state_chg(reset->fsm, ST_CONN, 0, 0);
	else {
		/* kick off reset-ack sending mechanism */
		osmo_fsm_inst_state_chg(reset->fsm, ST_DISC, RESET_RESEND_INTERVAL,
					RESET_RESEND_TIMER_NO);
	}

	return reset;
}

/* Tear down state machine */
void a_reset_free(struct a_reset_ctx *reset)
{
	OSMO_ASSERT(reset);
	OSMO_ASSERT(reset->fsm);

	osmo_fsm_inst_free(reset->fsm);
	reset->fsm = NULL;

	memset(reset, 0, sizeof(*reset));
	talloc_free(reset);
}

/* Confirm that we sucessfully received a reset acknowlege message */
void a_reset_ack_confirm(struct a_reset_ctx *reset)
{
	OSMO_ASSERT(reset);
	OSMO_ASSERT(reset->fsm);

	osmo_fsm_inst_dispatch(reset->fsm, EV_RESET_ACK, reset);
}

/* Report a failed connection */
void a_reset_conn_fail(struct a_reset_ctx *reset)
{
	/* If no reset context is supplied, just drop the info */
	if (!reset)
		return;

	OSMO_ASSERT(reset->fsm);

	osmo_fsm_inst_dispatch(reset->fsm, EV_N_DISCONNECT, reset);
}

/* Report a successful connection */
void a_reset_conn_success(struct a_reset_ctx *reset)
{
	/* If no reset context is supplied, just drop the info */
	if (!reset)
		return;

	OSMO_ASSERT(reset->fsm);

	osmo_fsm_inst_dispatch(reset->fsm, EV_N_CONNECT, reset);
}

/* Check if we have a connection to a specified msc */
bool a_reset_conn_ready(struct a_reset_ctx *reset)
{
	/* If no reset context is supplied, we assume that
	 * the connection can't be ready! */
	if (!reset)
		return false;

	OSMO_ASSERT(reset->fsm);
	if (reset->fsm->state == ST_CONN)
		return true;

	return false;
}
