/*
 * (C) 2014 by Holger Hans Peter Freyther
 * (C) 2014 by sysmocom s.f.m.c. GmbH
 *
 * All Rights Reserved
 *
 * 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/ctrl/control_cmd.h>
#include <openbsc/gsm_data.h>
#include <openbsc/gsm_subscriber.h>
#include <openbsc/db.h>
#include <openbsc/debug.h>

#include <stdbool.h>

static bool alg_supported(const char *alg)
{
	/*
	 * TODO: share this with the vty_interface and extend to all
	 * algorithms supported by libosmocore now. Make it table based
	 * as well.
	 */
	if (strcasecmp(alg, "none") == 0)
		return true;
	if (strcasecmp(alg, "xor") == 0)
		return true;
	if (strcasecmp(alg, "comp128v1") == 0)
		return true;
	return false;
}

static int verify_subscriber_modify(struct ctrl_cmd *cmd, const char *value, void *d)
{
	char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
	int rc = 0;

	tmp = talloc_strdup(cmd, value);
	if (!tmp)
		return 1;

	imsi = strtok_r(tmp, ",", &saveptr);
	msisdn = strtok_r(NULL, ",", &saveptr);
	alg = strtok_r(NULL, ",", &saveptr);
	ki = strtok_r(NULL, ",", &saveptr);

	if (!imsi || !msisdn)
		rc = 1;
	else if (strlen(imsi) > GSM23003_IMSI_MAX_DIGITS)
		rc = 1;
	else if (strlen(msisdn) >= GSM_EXTENSION_LENGTH)
		rc = 1;
	else if (alg) {
		if (!alg_supported(alg))
			rc = 1;
		else if (strcasecmp(alg, "none") != 0 && !ki)
			rc = 1;
	}

	talloc_free(tmp);
	return rc;
}

static int get_subscriber_modify(struct ctrl_cmd *cmd, void *data)
{
	cmd->reply = "Set only attribute";
	return CTRL_CMD_ERROR;
}

static int set_subscriber_modify(struct ctrl_cmd *cmd, void *data)
{
	struct gsm_network *net = cmd->node;
	char *tmp, *imsi, *msisdn, *alg, *ki, *saveptr = NULL;
	struct gsm_subscriber* subscr;
	int rc;

	tmp = talloc_strdup(cmd, cmd->value);
	if (!tmp)
		return 1;

	imsi = strtok_r(tmp, ",", &saveptr);
	msisdn = strtok_r(NULL, ",", &saveptr);
	alg = strtok_r(NULL, ",", &saveptr);
	ki = strtok_r(NULL, ",", &saveptr);

	subscr = subscr_get_by_imsi(net->subscr_group, imsi);
	if (!subscr)
		subscr = subscr_create_subscriber(net->subscr_group, imsi);
	if (!subscr)
		goto fail;

	subscr->authorized = 1;
	strncpy(subscr->extension, msisdn, GSM_EXTENSION_LENGTH - 1);
	subscr->extension[GSM_EXTENSION_LENGTH-1] = '\0';

	/* put it back to the db */
	rc = db_sync_subscriber(subscr);
	db_subscriber_update(subscr);

	/* handle optional ciphering */
	if (alg) {
		if (strcasecmp(alg, "none") == 0)
			db_sync_authinfo_for_subscr(NULL, subscr);
		else {
			struct gsm_auth_info ainfo = { 0, };
			/* the verify should make sure that this is okay */
			OSMO_ASSERT(alg);
			OSMO_ASSERT(ki);

			if (strcasecmp(alg, "xor") == 0)
				ainfo.auth_algo = AUTH_ALGO_XOR;
			else if (strcasecmp(alg, "comp128v1") == 0)
				ainfo.auth_algo = AUTH_ALGO_COMP128v1;

			rc = osmo_hexparse(ki, ainfo.a3a8_ki, sizeof(ainfo.a3a8_ki));
			if (rc < 0) {
				subscr_put(subscr);
				talloc_free(tmp);
				cmd->reply = "Failed to parse KI";
				return CTRL_CMD_ERROR;
			}

			ainfo.a3a8_ki_len = rc;
			db_sync_authinfo_for_subscr(&ainfo, subscr);
			rc = 0;
		}
		db_sync_lastauthtuple_for_subscr(NULL, subscr);
	}
	subscr_put(subscr);

	talloc_free(tmp);

	if (rc != 0) {
		cmd->reply = "Failed to store the record in the DB";
		return CTRL_CMD_ERROR;
	}

	cmd->reply = "OK";
	return CTRL_CMD_REPLY;

fail:
	talloc_free(tmp);
	cmd->reply = "Failed to create subscriber";
	return CTRL_CMD_ERROR;
}

CTRL_CMD_DEFINE(subscriber_modify, "subscriber-modify-v1");

static int verify_subscriber_delete(struct ctrl_cmd *cmd, const char *v, void *d)
{
	return 0;
}

static int get_subscriber_delete(struct ctrl_cmd *cmd, void *data)
{
	cmd->reply = "Set only attribute";
	return CTRL_CMD_ERROR;
}

static int set_subscriber_delete(struct ctrl_cmd *cmd, void *data)
{
	int was_used = 0;
	int rc;
	struct gsm_subscriber *subscr;
	struct gsm_network *net = cmd->node;

	subscr = subscr_get_by_imsi(net->subscr_group, cmd->value);
	if (!subscr) {
		cmd->reply = "Failed to find subscriber";
		return CTRL_CMD_ERROR;
	}

	if (subscr->use_count != 1) {
		LOGP(DCTRL, LOGL_NOTICE, "Going to remove active subscriber.\n");
		was_used = 1;
	}

	rc = db_subscriber_delete(subscr);
	subscr_put(subscr);

	if (rc != 0) {
		cmd->reply = "Failed to remove subscriber";
		return CTRL_CMD_ERROR;
	}

	cmd->reply = was_used ? "Removed active subscriber" : "Removed";
	return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE(subscriber_delete, "subscriber-delete-v1");

static int verify_subscriber_list(struct ctrl_cmd *cmd, const char *value, void *d)
{
	return 1;
}

static int set_subscriber_list(struct ctrl_cmd *cmd, void *d)
{
	cmd->reply = "Get only attribute";
	return CTRL_CMD_ERROR;
}

static void list_cb(struct gsm_subscriber *subscr, void *d)
{
	char **data = (char **) d;
	*data = talloc_asprintf_append(*data, "%s,%s\n",
				subscr->imsi, subscr->extension);
}

static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
{
	cmd->reply = talloc_strdup(cmd, "");

	db_subscriber_list_active(list_cb, &cmd->reply);
	printf("%s\n", cmd->reply);
	return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE(subscriber_list, "subscriber-list-active-v1");

int msc_ctrl_cmds_install(void)
{
	int rc = 0;

	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_modify);
	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_delete);
	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list);
	return rc;
}
