#include <osmocom/sgsn/gprs_gmm_attach.h>

#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/sgsn/debug.h>
#include <osmocom/sgsn/gprs_gmm.h>
#include <osmocom/sgsn/sgsn.h>

#define X(s) (1 << (s))

static int require_identity_imei = 1;
static int require_auth = 1;

static void st_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct sgsn_mm_ctx *ctx = fi->priv;
	struct msgb *attach_req = data;

	/* we can run st_init multiple times */
	if (ctx->gmm_att_req.attach_req)
		msgb_free(ctx->gmm_att_req.attach_req);

	ctx->gmm_att_req.attach_req = msgb_copy(attach_req, "Attach Request");
	ctx->auth_state = SGSN_AUTH_UNKNOWN;
	ctx->gmm_att_req.auth_reattempt = 0;

	/*
	 * TODO: remove pending_req as soon the sgsn_auth code doesn't depend
	 * on it.
	 * pending_req must be set, even this fsm doesn't use it, because
	 * the sgsn_auth code is using this too
	 */
	ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ;

	if (require_identity_imei) {
		ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMEI;
		osmo_fsm_inst_state_chg(fi, ST_IDENTIY, sgsn->cfg.timers.T3370, 3370);
	} else if (!strlen(ctx->imsi)) {
		ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMSI;
		osmo_fsm_inst_state_chg(fi, ST_IDENTIY, sgsn->cfg.timers.T3370, 3370);
	} else if (require_auth)
		osmo_fsm_inst_state_chg(fi, ST_AUTH, sgsn->cfg.timers.T3360, 3360);
	else
		osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350);
}

static void st_identity_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct sgsn_mm_ctx *ctx = fi->priv;
	int ret = 0;

	ctx->num_T_exp = 0;

	switch (ctx->gmm_att_req.id_type) {
	case GSM_MI_TYPE_IMEI:
	case GSM_MI_TYPE_IMSI:
		break;
	default:
		/* TODO logging */
		osmo_fsm_inst_dispatch(fi, E_REJECT, NULL);
		return;
	}

	ctx->t3370_id_type = ctx->gmm_att_req.id_type;
	ret = gsm48_tx_gmm_id_req(ctx, ctx->gmm_att_req.id_type);
	if (ret < 0) {
		LOGPFSM(fi, "Can not send tx_gmm_id %d.\n", ret);
		osmo_fsm_inst_dispatch(fi, E_REJECT, NULL);
	}
}

static void st_identity(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct sgsn_mm_ctx *ctx = fi->priv;

	OSMO_ASSERT(event == E_IDEN_RESP_RECV);

	/* check if we received a identity response */
	long type = (long) data;
	switch (type) {
	case GSM_MI_TYPE_IMEI:
	case GSM_MI_TYPE_IMSI:
		break;
	default:
		LOGMMCTXP(LOGL_ERROR, ctx, "Unknown mi type: 0x%lx, rejecting MS.\n", type);
		osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_NET_FAIL);
		return;
	}

	if (type != ctx->gmm_att_req.id_type) {
		/* ignore wrong package */
		/* TODO logging */
		return;
	}

	if (type == GSM_MI_TYPE_IMEI && !strlen(ctx->imsi)) {
		ctx->gmm_att_req.id_type = GSM_MI_TYPE_IMSI;
		osmo_fsm_inst_state_chg(fi, ST_IDENTIY, sgsn->cfg.timers.T3370, 3370);
	} else if (require_auth)
		osmo_fsm_inst_state_chg(fi, ST_AUTH, sgsn->cfg.timers.T3360, 3360);
	else
		osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350);
}

static void st_auth_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct sgsn_mm_ctx *ctx = fi->priv;
	enum sgsn_auth_state auth_state;

	ctx->num_T_exp = 0;

	/* TODO: remove this layer violation. Don't parse any auth_policy here
	 * The correct way would be to ask the SGSN is this mmctx has to be auth
	 * regardless of the state.
	 * Otherwise someone else could steal the TLLI and just use it without further
	 * auth.
	 */
	if (sgsn->cfg.auth_policy != SGSN_AUTH_POLICY_REMOTE) {
		/* we can "trust" sgsn_auth_state as long it's not remote */
		auth_state = sgsn_auth_state(ctx);
	} else {
		auth_state = ctx->auth_state;
	}

	switch(auth_state) {
	case SGSN_AUTH_UMTS_RESYNC: /* ask the vlr for a new vector to match the simcards seq */
	case SGSN_AUTH_UNKNOWN: /* the SGSN doesn know this MS */
		osmo_fsm_inst_state_chg(fi, ST_ASK_VLR, sgsn->cfg.timers.T3350, 3350);
		break;
	case SGSN_AUTH_REJECTED:
		/* TODO: correct GMM cause */
		osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_GPRS_NOTALLOWED);
		break;
	case SGSN_AUTH_ACCEPTED:
		osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350);
		break;
	case SGSN_AUTH_AUTHENTICATE:
		if (ctx->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
			/* invalid key material */
			osmo_fsm_inst_state_chg(fi, ST_ASK_VLR, sgsn->cfg.timers.T3350, 3350);
		}

		struct gsm_auth_tuple *at = &ctx->auth_triplet;
		if (gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq,
					       false) < 0) {
			/* network failure */
			osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_NET_FAIL);
		}
		ctx->gmm_att_req.auth_reattempt++;
		break;
	}
}

static void st_auth(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct sgsn_mm_ctx *ctx = fi->priv;

	switch (event) {
	case E_AUTH_RESP_RECV_SUCCESS:
		sgsn_auth_request(ctx);
		osmo_fsm_inst_state_chg(fi, ST_ACCEPT, sgsn->cfg.timers.T3350, 3350);
		break;
	case E_AUTH_RESP_RECV_RESYNC:
		if (ctx->gmm_att_req.auth_reattempt <= 1)
			osmo_fsm_inst_state_chg(fi, ST_ASK_VLR, sgsn->cfg.timers.T3350, 3350);
		else
			osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_CAUSE_SYNC_FAIL);
		break;
	}
}

static void st_accept_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct sgsn_mm_ctx *ctx = fi->priv;

	ctx->num_T_exp = 0;

	/* TODO: remove pending_req as soon the sgsn_auth code doesn't depend on it */
	ctx->pending_req = 0;
	gsm48_tx_gmm_att_ack(ctx);
}

static void st_accept(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct sgsn_mm_ctx *ctx = fi->priv;

	switch(event) {
	case E_ATTACH_COMPLETE_RECV:
		/* TODO: #ifdef ! PTMSI_ALLOC is not supported */
		extract_subscr_msisdn(ctx);
		extract_subscr_hlr(ctx);
		osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
		break;
	}
}

static void st_reject(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct sgsn_mm_ctx *ctx = fi->priv;
	long reject_cause = (long) data;

	if (reject_cause != GMM_DISCARD_MS_WITHOUT_REJECT)
		gsm48_tx_gmm_att_rej(ctx, (uint8_t) reject_cause);

	sgsn_mm_ctx_cleanup_free(ctx);
}

static void st_ask_vlr_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
	struct sgsn_mm_ctx *ctx = fi->priv;

	/* FIXME: remove this layer violation.
	 * The VLR should send the message to the HLR and not the rx function
	 * gsm48_rx_gmm_auth_ciph_fail. Because gmm_auth_ciph_fail already send a
	 * message to the HLR, we don't send here a request. */
	if (ctx->auth_state == SGSN_AUTH_UMTS_RESYNC)
		return;

	/* ask the auth layer for more data */
	sgsn_auth_request(ctx);
}

static void st_ask_vlr(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	switch(event) {
	case E_VLR_ANSWERED:
		osmo_fsm_inst_state_chg(fi, ST_AUTH, sgsn->cfg.timers.T3360, 3360);
		break;
	}
}

static struct osmo_fsm_state gmm_attach_req_fsm_states[] = {
	/* default state for non-DTX and DTX when SPEECH is in progress */
	[ST_INIT] = {
		.in_event_mask = X(E_ATTACH_REQ_RECV),
		.out_state_mask = X(ST_INIT) | X(ST_IDENTIY) | X(ST_AUTH) | X(ST_ACCEPT),
		.name = "Init",
		.action = st_init,
	},
	[ST_ASK_VLR] = {
		.in_event_mask = X(E_VLR_ANSWERED),
		.out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_REJECT),
		.name = "AskVLR",
		.onenter = st_ask_vlr_on_enter,
		.action = st_ask_vlr,
	},
	[ST_IDENTIY] = {
		.in_event_mask = X(E_IDEN_RESP_RECV),
		.out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_IDENTIY) | X(ST_REJECT),
		.onenter = st_identity_on_enter,
		.name = "CheckIdentity",
		.action = st_identity,
	},
	[ST_AUTH] = {
		.in_event_mask = X(E_AUTH_RESP_RECV_SUCCESS) | X(E_AUTH_RESP_RECV_RESYNC),
		.out_state_mask = X(ST_INIT) | X(ST_AUTH) | X(ST_ACCEPT) | X(ST_ASK_VLR) | X(ST_REJECT),
		.name = "Authenticate",
		.onenter = st_auth_on_enter,
		.action = st_auth,
	},
	[ST_ACCEPT] = {
		.in_event_mask = X(E_ATTACH_COMPLETE_RECV),
		.out_state_mask = X(ST_INIT) | X(ST_REJECT),
		.name = "WaitAttachComplete",
		.onenter = st_accept_on_enter,
		.action = st_accept,
	},
	[ST_REJECT] = {
		.in_event_mask = X(E_REJECT),
		.out_state_mask = X(ST_INIT),
		.name = "Reject",
		.action = st_reject,
	},
};

const struct value_string gmm_attach_req_fsm_event_names[] = {
	{ E_ATTACH_REQ_RECV,		"Received an attach request" },
	{ E_IDEN_RESP_RECV,		"Identity Request received" },
	{ E_AUTH_RESP_RECV_SUCCESS,	"Authentication Response received" },
	{ E_AUTH_RESP_RECV_RESYNC,	"Authentication Failure with resync received" },
	{ E_ATTACH_ACCEPTED,		"Attach accepted" },
	{ E_ATTACH_ACCEPT_SENT,		"Attach accept sent" },
	{ E_ATTACH_COMPLETE_RECV, 	"Attach complete received." },
	{ E_REJECT,			"Reject the MS"},
	{ E_VLR_ANSWERED,		"VLR answered"},
	{ 0,				NULL }
};

void gmm_attach_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data) {
	struct sgsn_mm_ctx *ctx = fi->priv;
	struct msgb *new_attach_req = data;

	switch (event) {
	case E_ATTACH_REQ_RECV:
		switch (fi->state) {
		case ST_INIT:
		case ST_REJECT:
			st_init(fi, event, data);
			break;

		case ST_ACCEPT:
			/* TODO: drop all state (e.g. PDP Ctx) and do this procedure */
			osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
			st_init(fi, event, data);
			break;

		case ST_ASK_VLR:
		case ST_AUTH:
		case ST_IDENTIY:
		case ST_RETRIEVE_AUTH:
			/* 04.08 4.7.3.1.6 d) Abnormal Case
			 * Only do action if Req IEs differs. */
			if (ctx->gmm_att_req.attach_req &&
					gprs_gmm_attach_req_ies(new_attach_req, ctx->gmm_att_req.attach_req)) {
				osmo_fsm_inst_state_chg(fi, ST_INIT, 0, 0);
				st_init(fi, event, data);
			}
			break;
		}
		break;
	case E_REJECT:
		if (fi->state != ST_REJECT)
			osmo_fsm_inst_state_chg(fi, ST_REJECT, 0, 0);
		st_reject(fi, event, data);
		break;
	}
}

int gmm_attach_timer_cb(struct osmo_fsm_inst *fi)
{
	struct sgsn_mm_ctx *ctx = fi->priv;
	struct gsm_auth_tuple *at = &ctx->auth_triplet;

	ctx->num_T_exp++;

	switch(fi->state) {
	case ST_ASK_VLR:
		/* TODO: replace T3350 by a better timer or it's own
		 * re-use T3350 - not defined by standard */
		LOGMMCTXP(LOGL_ERROR, ctx, "HLR did not answer in time. Rejecting.\n");
		osmo_fsm_inst_dispatch(fi, E_REJECT,
				       (void *) GMM_CAUSE_NET_FAIL);
		break;
	case ST_IDENTIY:
		/* T3370 */
		if (ctx->num_T_exp >= 5) {
			osmo_fsm_inst_dispatch(fi, E_REJECT,
					       (void *) GMM_CAUSE_MS_ID_NOT_DERIVED);
			break;
		}
		gsm48_tx_gmm_id_req(ctx, ctx->gmm_att_req.id_type);
		osmo_timer_schedule(&fi->timer, sgsn->cfg.timers.T3370, 0);
		break;
	case ST_AUTH:
		/* T3360 */
		if (ctx->num_T_exp >= 5) {
			osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_DISCARD_MS_WITHOUT_REJECT);
			break;
		}
		gsm48_tx_gmm_auth_ciph_req(ctx, &at->vec, at->key_seq, false);
		osmo_timer_schedule(&fi->timer, sgsn->cfg.timers.T3360, 0);
		break;
	case ST_ACCEPT:
		/* T3350 */
		if (ctx->num_T_exp >= 5) {
			osmo_fsm_inst_dispatch(fi, E_REJECT, (void *) GMM_DISCARD_MS_WITHOUT_REJECT);
			break;
		}
		gsm48_tx_gmm_att_ack(ctx);
		osmo_timer_schedule(&fi->timer, sgsn->cfg.timers.T3350, 0);
		break;
	}

	return 0;
}

struct osmo_fsm gmm_attach_req_fsm = {
	.name = "GMM_ATTACH_REQ_FSM",
	.states = gmm_attach_req_fsm_states,
	.num_states = ARRAY_SIZE(gmm_attach_req_fsm_states),
	.event_names = gmm_attach_req_fsm_event_names,
	.allstate_event_mask = X(E_REJECT) | X(E_ATTACH_REQ_RECV),
	.allstate_action = gmm_attach_allstate_action,
	.log_subsys = DMM,
	.timer_cb = gmm_attach_timer_cb,
};

static __attribute__((constructor)) void gprs_gmm_fsm_init(void)
{
	osmo_fsm_register(&gmm_attach_req_fsm);
}

void gmm_att_req_free(struct sgsn_mm_ctx *mm) {
	if (mm->gmm_att_req.fsm)
		osmo_fsm_inst_free(mm->gmm_att_req.fsm);

	if (mm->gmm_att_req.attach_req)
		msgb_free(mm->gmm_att_req.attach_req);
}
