/* (C) 2015-2023 by Harald Welte <laforge@gnumonks.org>
 *
 * 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/>.
 *
 */

#define _POSIX_C_SOURCE 200809L /* for strptime(3) */
/* These are needed as well due to the above _POSIX_C_SOURCE definition: */
#define _DEFAULT_SOURCE		/* for struct timezone */
#define _XOPEN_SOURCE		/* for clockid_t */

#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <time.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
#include <osmocom/crypt/auth.h>
#include <osmocom/gsm/gsm23003.h>

#include <sqlite3.h>

#include <osmocom/hlr/logging.h>
#include <osmocom/hlr/hlr.h>
#include <osmocom/hlr/db.h>
#include <osmocom/gsupclient/cni_peer_id.h>

#define LOGHLR(imsi, level, fmt, args ...)	LOGP(DAUC, level, "IMSI='%s': " fmt, imsi, ## args)

/*! Add new subscriber record to the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits, is validated.
 * \param[in] flags  Bitmask of DB_SUBSCR_FLAG_*.
 * \returns 0 on success, -EINVAL on invalid IMSI, -EEXIST if subscriber with
 *          provided imsi already exists, -EIO on other database errors.
 */
int db_subscr_create(struct db_context *dbc, const char *imsi, uint8_t flags)
{
	sqlite3_stmt *stmt;
	int rc;

	if (!osmo_imsi_str_valid(imsi)) {
		LOGP(DAUC, LOGL_ERROR, "Cannot create subscriber: invalid IMSI: '%s'\n",
		     imsi);
		return -EINVAL;
	}

	stmt = dbc->stmt[DB_STMT_SUBSCR_CREATE];

	if (!db_bind_text(stmt, "$imsi", imsi))
		return -EIO;
	if (!db_bind_int(stmt, "$nam_cs", (flags & DB_SUBSCR_FLAG_NAM_CS) != 0))
		return -EIO;
	if (!db_bind_int(stmt, "$nam_ps", (flags & DB_SUBSCR_FLAG_NAM_PS) != 0))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	db_remove_reset(stmt);
	if (rc != SQLITE_DONE) {
		LOGHLR(imsi, LOGL_ERROR, "Cannot create subscriber: SQL error: (%d) %s\n",
		       rc, sqlite3_errmsg(dbc->db));
		if (rc == SQLITE_CONSTRAINT_UNIQUE)
			return -EEXIST;
		return -EIO;
	}

	return 0;
}

/*! Completely delete a subscriber record from the HLR database.
 * Also remove authentication data.
 * Future todo: also drop from all other database tables, which aren't used yet
 * at the time of writing this.
 * \param[in,out] dbc  database context.
 * \param[in] subscr_id  ID of the subscriber in the HLR db.
 * \returns if the subscriber was found and removed, -EIO on database error,
 *          -ENOENT if no such subscriber data exists.
 */
int db_subscr_delete_by_id(struct db_context *dbc, int64_t subscr_id)
{
	int rc;
	struct sub_auth_data_str aud;
	int ret = 0;

	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_DEL_BY_ID];

	if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR,
		       "Cannot delete subscriber ID=%" PRId64 ": SQL error: (%d) %s\n",
		       subscr_id, rc, sqlite3_errmsg(dbc->db));
		db_remove_reset(stmt);
		return -EIO;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot delete: no such subscriber: ID=%" PRId64 "\n",
		     subscr_id);
		ret = -ENOENT;
	} else if (rc != 1) {
		LOGP(DAUC, LOGL_ERROR, "Delete subscriber ID=%" PRId64
		     ": SQL modified %d rows (expected 1)\n", subscr_id, rc);
		ret = -EIO;
	}
	db_remove_reset(stmt);

	/* make sure to remove authentication data for this subscriber id, for
	 * both 2G and 3G. */

	aud = (struct sub_auth_data_str){
		.type = OSMO_AUTH_TYPE_GSM,
		.algo = OSMO_AUTH_ALG_NONE,
	};
	rc = db_subscr_update_aud_by_id(dbc, subscr_id, &aud);
	if (ret == -ENOENT && !rc)
		ret = 0;

	aud = (struct sub_auth_data_str){
		.type = OSMO_AUTH_TYPE_UMTS,
		.algo = OSMO_AUTH_ALG_NONE,
	};
	rc = db_subscr_update_aud_by_id(dbc, subscr_id, &aud);
	if (ret == -ENOENT && !rc)
		ret = 0;

	return ret;
}

/*! Set a subscriber's MSISDN in the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits
 * \param[in] msisdn  ASCII string of MSISDN digits, or NULL to remove the MSISDN.
 * \returns 0 on success, -EINVAL in case of invalid MSISDN string, -EIO on
 *          database failure, -ENOENT if no such subscriber exists.
 */
int db_subscr_update_msisdn_by_imsi(struct db_context *dbc, const char *imsi,
				    const char *msisdn)
{
	int rc;
	int ret = 0;

	if (msisdn && !osmo_msisdn_str_valid(msisdn)) {
		LOGHLR(imsi, LOGL_ERROR,
		       "Cannot update subscriber: invalid MSISDN: '%s'\n",
		       msisdn);
		return -EINVAL;
	}

	sqlite3_stmt *stmt = dbc->stmt[
		msisdn ? DB_STMT_SET_MSISDN_BY_IMSI : DB_STMT_DELETE_MSISDN_BY_IMSI];

	if (!db_bind_text(stmt, "$imsi", imsi))
		return -EIO;
	if (msisdn) {
		if (!db_bind_text(stmt, "$msisdn", msisdn))
			return -EIO;
	}

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGHLR(imsi, LOGL_ERROR,
		       "Cannot update subscriber's MSISDN: SQL error: (%d) %s\n",
		       rc, sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot update MSISDN: no such subscriber: IMSI='%s'\n",
		     imsi);
		ret = -ENOENT;
		goto out;
	} else if (rc != 1) {
		LOGHLR(imsi, LOGL_ERROR, "Update MSISDN: SQL modified %d rows (expected 1)\n", rc);
		ret = -EIO;
	}

out:
	db_remove_reset(stmt);
	return ret;

}

/*! Insert or update 2G or 3G authentication tokens in the database.
 * If aud->type is OSMO_AUTH_TYPE_GSM, the auc_2g table entry for the
 * subscriber will be added or modified; if aud->algo is OSMO_AUTH_ALG_NONE,
 * however, the auc_2g entry for the subscriber is deleted. If aud->type is
 * OSMO_AUTH_TYPE_UMTS, the auc_3g table is updated; again, if aud->algo is
 * OSMO_AUTH_ALG_NONE, the auc_3g entry is deleted.
 * \param[in,out] dbc  database context.
 * \param[in] subscr_id  DB ID of the subscriber.
 * \param[in] aud  Pointer to new auth data (in ASCII string form).
 * \returns 0 on success, -EINVAL for invalid aud, -ENOENT for unknown
 *          subscr_id, -EIO for database errors.
 */
int db_subscr_update_aud_by_id(struct db_context *dbc, int64_t subscr_id,
			       const struct sub_auth_data_str *aud)
{
	sqlite3_stmt *stmt_del;
	sqlite3_stmt *stmt_ins;
	sqlite3_stmt *stmt;
	const char *label;
	int rc;
	int ret = 0;

	switch (aud->type) {
	case OSMO_AUTH_TYPE_GSM:
		label = "auc_2g";
		stmt_del = dbc->stmt[DB_STMT_AUC_2G_DELETE];
		stmt_ins = dbc->stmt[DB_STMT_AUC_2G_INSERT];

		switch (aud->algo) {
		case OSMO_AUTH_ALG_NONE:
		case OSMO_AUTH_ALG_COMP128v1:
		case OSMO_AUTH_ALG_COMP128v2:
		case OSMO_AUTH_ALG_COMP128v3:
		case OSMO_AUTH_ALG_XOR_2G:
			break;
		case OSMO_AUTH_ALG_XOR_3G:
		case OSMO_AUTH_ALG_MILENAGE:
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " auth algo not suited for 2G: %s\n",
			     osmo_auth_alg_name(aud->algo));
			return -EINVAL;
		default:
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Unknown auth algo: %d\n", aud->algo);
			return -EINVAL;
		}

		if (aud->algo == OSMO_AUTH_ALG_NONE)
			break;
		if (!osmo_is_hexstr(aud->u.gsm.ki, 32, 32, true)) {
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Invalid KI: '%s'\n", aud->u.gsm.ki);
			return -EINVAL;
		}
		break;

	case OSMO_AUTH_TYPE_UMTS:
		label = "auc_3g";
		stmt_del = dbc->stmt[DB_STMT_AUC_3G_DELETE];
		stmt_ins = dbc->stmt[DB_STMT_AUC_3G_INSERT];
		switch (aud->algo) {
		case OSMO_AUTH_ALG_NONE:
		case OSMO_AUTH_ALG_MILENAGE:
		case OSMO_AUTH_ALG_XOR_3G:
			break;
		case OSMO_AUTH_ALG_COMP128v1:
		case OSMO_AUTH_ALG_COMP128v2:
		case OSMO_AUTH_ALG_COMP128v3:
		case OSMO_AUTH_ALG_XOR_2G:
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " auth algo not suited for 3G: %s\n",
			     osmo_auth_alg_name(aud->algo));
			return -EINVAL;
		default:
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Unknown auth algo: %d\n", aud->algo);
			return -EINVAL;
		}

		if (aud->algo == OSMO_AUTH_ALG_NONE)
			break;
		if (!osmo_is_hexstr(aud->u.umts.k, 32, 64, true)) {
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Invalid K: '%s'\n", aud->u.umts.k);
			return -EINVAL;
		}
		if (!osmo_is_hexstr(aud->u.umts.opc, 32, 64, true)) {
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Invalid OP/OPC: '%s'\n", aud->u.umts.opc);
			return -EINVAL;
		}
		if (aud->u.umts.ind_bitlen > OSMO_MILENAGE_IND_BITLEN_MAX) {
			LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
			     " Invalid ind_bitlen: %d\n", aud->u.umts.ind_bitlen);
			return -EINVAL;
		}
		break;
	default:
		LOGP(DAUC, LOGL_ERROR, "Cannot update auth tokens:"
		     " unknown auth type: %d\n", aud->type);
		return -EINVAL;
	}

	stmt = stmt_del;

	if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR,
		     "Cannot delete %s row: SQL error: (%d) %s\n",
		     label, rc, sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc)
		/* Leave "no such entry" logging to the caller -- during
		 * db_subscr_delete_by_id(), we call this to make sure it is
		 * empty, and no entry is not an error then.*/
		ret = -ENOENT;
	else if (rc != 1) {
		LOGP(DAUC, LOGL_ERROR, "Delete subscriber ID=%" PRId64
		     " from %s: SQL modified %d rows (expected 1)\n",
		     subscr_id, label, rc);
		ret = -EIO;
	}

	db_remove_reset(stmt);

	/* Error situation? Return now. */
	if (ret && ret != -ENOENT)
		return ret;

	/* Just delete requested? */
	if (aud->algo == OSMO_AUTH_ALG_NONE)
		return ret;

	/* Don't return -ENOENT if inserting new data. */
	ret = 0;

	/* Insert new row */
	stmt = stmt_ins;

	if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
		return -EIO;

	switch (aud->type) {
	case OSMO_AUTH_TYPE_GSM:
		if (!db_bind_int(stmt, "$algo_id_2g", aud->algo))
			return -EIO;
		if (!db_bind_text(stmt, "$ki", aud->u.gsm.ki))
			return -EIO;
		break;
	case OSMO_AUTH_TYPE_UMTS:
		if (!db_bind_int(stmt, "$algo_id_3g", aud->algo))
			return -EIO;
		if (!db_bind_text(stmt, "$k", aud->u.umts.k))
			return -EIO;
		if (!db_bind_text(stmt, "$op",
				  aud->u.umts.opc_is_op ? aud->u.umts.opc : NULL))
			return -EIO;
		if (!db_bind_text(stmt, "$opc",
				  aud->u.umts.opc_is_op ? NULL : aud->u.umts.opc))
			return -EIO;
		if (!db_bind_int(stmt, "$ind_bitlen", aud->u.umts.ind_bitlen))
			return -EIO;
		break;
	default:
		OSMO_ASSERT(false);
	}

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR,
		     "Cannot insert %s row: SQL error: (%d) %s\n",
		     label, rc, sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

out:
	db_remove_reset(stmt);
	return ret;
}

/*! Set a subscriber's IMEI in the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits
 * \param[in] imei  ASCII string of identifier digits, or NULL to remove the IMEI.
 * \returns 0 on success, -ENOENT when the given subscriber does not exist,
 *         -EIO on database errors.
 */
int db_subscr_update_imei_by_imsi(struct db_context *dbc, const char* imsi, const char *imei)
{
	int rc, ret = 0;
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_UPD_IMEI_BY_IMSI];

	if (imei && !osmo_imei_str_valid(imei, false)) {
		LOGP(DAUC, LOGL_ERROR, "Cannot update subscriber IMSI='%s': invalid IMEI: '%s'\n", imsi, imei);
		return -EINVAL;
	}

	if (!db_bind_text(stmt, "$imsi", imsi))
		return -EIO;
	if (imei && !db_bind_text(stmt, "$imei", imei))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR, "Update IMEI for subscriber IMSI='%s': SQL Error: %s\n", imsi,
		     sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot update IMEI for subscriber IMSI='%s': no such subscriber\n", imsi);
		ret = -ENOENT;
	} else if (rc != 1) {
		LOGP(DAUC, LOGL_ERROR, "Update IMEI for subscriber IMSI='%s': SQL modified %d rows (expected 1)\n",
		     imsi, rc);
		ret = -EIO;
	}

out:
	db_remove_reset(stmt);
	return ret;
}

static void parse_last_lu_seen(time_t *dst, const char *last_lu_seen_str, const char *imsi, const char *label)
{
	struct tm tm = {0};
	time_t val;
	if (!last_lu_seen_str || last_lu_seen_str[0] == '\0')
		return;

	if (strptime(last_lu_seen_str, DB_LAST_LU_SEEN_FMT, &tm) == NULL) {
		LOGP(DAUC, LOGL_ERROR, "IMSI-%s: Last LU Seen %s: Cannot parse timestamp '%s'\n",
		     imsi, label, last_lu_seen_str);
		return;
	}

	errno = 0;
	val = mktime(&tm);
	if (val == -1) {
		LOGP(DAUC, LOGL_ERROR, "IMSI-%s: Last LU Seen %s: Cannot convert timestamp '%s' to time_t: %s\n",
		     imsi, label, last_lu_seen_str, strerror(errno));
		val = 0;
	}

	*dst = val;
}

/* Common code for db_subscr_get_by_*() functions. */
static int db_sel(struct db_context *dbc, sqlite3_stmt *stmt, struct hlr_subscriber *subscr,
		  const char **err)
{
	int rc;
	int ret = 0;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc == SQLITE_DONE) {
		ret = -ENOENT;
		goto out;
	}
	if (rc != SQLITE_ROW) {
		ret = -EIO;
		goto out;
	}

	if (!subscr)
		goto out;

	*subscr = (struct hlr_subscriber){};

	/* obtain the various columns */
	subscr->id = sqlite3_column_int64(stmt, 0);
	copy_sqlite3_text_to_buf(subscr->imsi, stmt, 1);
	copy_sqlite3_text_to_buf(subscr->msisdn, stmt, 2);
	copy_sqlite3_text_to_buf(subscr->imei, stmt, 3);
	/* FIXME: These should all be BLOBs as they might contain NUL */
	copy_sqlite3_text_to_buf(subscr->vlr_number, stmt, 4);
	copy_sqlite3_text_to_buf(subscr->sgsn_number, stmt, 5);
	copy_sqlite3_text_to_buf(subscr->sgsn_address, stmt, 6);
	subscr->periodic_lu_timer = sqlite3_column_int(stmt, 7);
	subscr->periodic_rau_tau_timer = sqlite3_column_int(stmt, 8);
	subscr->nam_cs = sqlite3_column_int(stmt, 9);
	subscr->nam_ps = sqlite3_column_int(stmt, 10);
	subscr->lmsi = sqlite3_column_int(stmt, 11);
	subscr->ms_purged_cs = sqlite3_column_int(stmt, 12);
	subscr->ms_purged_ps = sqlite3_column_int(stmt, 13);
	parse_last_lu_seen(&subscr->last_lu_seen, (const char *)sqlite3_column_text(stmt, 14),
			   subscr->imsi, "CS");
	parse_last_lu_seen(&subscr->last_lu_seen_ps, (const char *)sqlite3_column_text(stmt, 15),
			   subscr->imsi, "PS");
	copy_sqlite3_text_to_ipa_name(&subscr->vlr_via_proxy, stmt, 16);
	copy_sqlite3_text_to_ipa_name(&subscr->sgsn_via_proxy, stmt, 17);

out:
	db_remove_reset(stmt);

	switch (ret) {
	case 0:
		*err = NULL;
		break;
	case -ENOENT:
		*err = "No such subscriber";
		break;
	default:
		*err = sqlite3_errmsg(dbc->db);
		break;
	}
	return ret;
}

/*! Check if a subscriber exists in the HLR database.
 * \param[in, out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits.
 * \returns 0 if it exists, -ENOENT if it does not exist, -EIO on database error.
 */
int db_subscr_exists_by_imsi(struct db_context *dbc, const char *imsi) {
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_EXISTS_BY_IMSI];
	const char *err;
	int rc;

	if (!db_bind_text(stmt, NULL, imsi))
		return -EIO;

	rc = sqlite3_step(stmt);
	db_remove_reset(stmt);
	if (rc == SQLITE_ROW)
		return 0; /* exists */
	if (rc == SQLITE_DONE)
		return -ENOENT; /* does not exist */

	err = sqlite3_errmsg(dbc->db);
	LOGP(DAUC, LOGL_ERROR, "Failed to check if subscriber exists by IMSI='%s': %s\n", imsi, err);
	return rc;
}

/*! Retrieve subscriber data from the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits.
 * \param[out] subscr  place retrieved data in this struct.
 * \returns 0 on success, -ENOENT if no such subscriber was found, -EIO on
 *          database error.
 */
int db_subscr_get_by_imsi(struct db_context *dbc, const char *imsi,
			  struct hlr_subscriber *subscr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_SEL_BY_IMSI];
	const char *err;
	int rc;

	if (!db_bind_text(stmt, NULL, imsi))
		return -EIO;

	rc = db_sel(dbc, stmt, subscr, &err);
	if (rc && rc != -ENOENT)
		LOGP(DAUC, LOGL_ERROR, "Cannot read subscriber from db: IMSI='%s': %s\n",
		     imsi, err);
	return rc;
}

/*! Check if a subscriber exists in the HLR database.
 * \param[in, out] dbc  database context.
 * \param[in] msisdn  ASCII string of MSISDN digits.
 * \returns 0 if it exists, -ENOENT if it does not exist, -EIO on database error.
 */
int db_subscr_exists_by_msisdn(struct db_context *dbc, const char *msisdn)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_EXISTS_BY_MSISDN];
	const char *err;
	int rc;

	if (!db_bind_text(stmt, NULL, msisdn))
		return -EIO;

	rc = sqlite3_step(stmt);
	db_remove_reset(stmt);
	if (rc == SQLITE_ROW)
		return 0; /* exists */
	if (rc == SQLITE_DONE)
		return -ENOENT; /* does not exist */

	err = sqlite3_errmsg(dbc->db);
	LOGP(DAUC, LOGL_ERROR, "Failed to check if subscriber exists "
		"by MSISDN='%s': %s\n", msisdn, err);
	return rc;
}

/*! Retrieve subscriber data from the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] msisdn  ASCII string of MSISDN digits.
 * \param[out] subscr  place retrieved data in this struct.
 * \returns 0 on success, -ENOENT if no such subscriber was found, -EIO on
 *          database error.
 */
int db_subscr_get_by_msisdn(struct db_context *dbc, const char *msisdn,
			    struct hlr_subscriber *subscr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_SEL_BY_MSISDN];
	const char *err;
	int rc;

	if (!db_bind_text(stmt, NULL, msisdn))
		return -EIO;

	rc = db_sel(dbc, stmt, subscr, &err);
	if (rc && rc != -ENOENT)
		LOGP(DAUC, LOGL_ERROR, "Cannot read subscriber from db: MSISDN='%s': %s\n",
		     msisdn, err);
	return rc;
}

/*! Retrieve subscriber data from the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] filter_type  ASCII string of identifier type to search.
 * \param[in] filter  ASCII string to search.
 * \param[in] get_cb  pointer to call back function for data.
 * \param[in,out] data  pointer to pass to callback function.
 * \param[in,out] count  counter for number of matched subscribers.
 * \param[in,our] err
 * \returns 0 on success, -ENOENT if no subscriber was found, -EIO on
 *          database error.
 */
int db_subscrs_get(struct db_context *dbc, const char *filter_type, const char *filter,
		   void (*get_cb)(struct hlr_subscriber *subscr, void *data), void *data,
		   int *count, const char **err)
{
	sqlite3_stmt *stmt;
	char search[256];
	int rc;
	struct hlr_subscriber subscr;
	bool show_ls = false;

	if (!filter_type) {
		stmt = dbc->stmt[DB_STMT_SEL_ALL];
	} else if (strcmp(filter_type, "imei") == 0) {
		stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMEI];
	} else if (strcmp(filter_type, "imsi") == 0) {
		stmt = dbc->stmt[DB_STMT_SEL_FILTER_IMSI];
	} else if (strcmp(filter_type, "msisdn") == 0) {
		stmt = dbc->stmt[DB_STMT_SEL_FILTER_MSISDN];
	} else if (strcmp(filter_type, "cs") == 0) {
		stmt = dbc->stmt[DB_STMT_SEL_FILTER_CS];
	} else if (strcmp(filter_type, "ps") == 0) {
		stmt = dbc->stmt[DB_STMT_SEL_FILTER_PS];
	} else if (strcmp(filter_type, "last_lu_seen") == 0) {
		show_ls = true;
		stmt = dbc->stmt[DB_STMT_SEL_ALL_ORDER_LAST_SEEN];
	} else {
		return -EIO;
	}

	if (filter_type && filter && strcmp(filter_type, "last_lu_seen") != 0) {
		if (strcmp(filter, "on") == 0) {
			sprintf(search, "%s", "1");
		} else if (strcmp(filter, "off") == 0) {
			sprintf(search, "%s", "0");
		} else {
			sprintf(search, "%%%s%%", filter);
		}
		if (!db_bind_text(stmt, "$search", search)) {
			*err = sqlite3_errmsg(dbc->db);
			return -EIO;
		}
	}

	rc = sqlite3_step(stmt);

	if (rc == SQLITE_DONE) {
		db_remove_reset(stmt);
		*err = "No matching subscriber(s)";
		return -ENOENT;
	}

	while (rc == SQLITE_ROW) {
		subscr = (struct hlr_subscriber){
			  .id = sqlite3_column_int64(stmt, 0),};
		copy_sqlite3_text_to_buf(subscr.imsi, stmt, 1);
		copy_sqlite3_text_to_buf(subscr.msisdn, stmt, 2);
		copy_sqlite3_text_to_buf(subscr.imei, stmt, 3);
		subscr.nam_cs = sqlite3_column_int(stmt, 9);
		subscr.nam_ps = sqlite3_column_int(stmt, 10);
		if (show_ls)
			parse_last_lu_seen(&subscr.last_lu_seen, (const char *)sqlite3_column_text(stmt, 14),
					   subscr.imsi, "CS");
		get_cb(&subscr, data);
		rc = sqlite3_step(stmt);
		(*count)++;
	}

	db_remove_reset(stmt);
	if (rc != SQLITE_DONE) {
		*err = sqlite3_errmsg(dbc->db);
		LOGP(DAUC, LOGL_ERROR, "Cannot read subscribers from db:: %s\n", *err);
		return rc;
	}
	*err = NULL;
	return 0;
}

/*! Retrieve subscriber data from the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] id  ID of the subscriber in the HLR db.
 * \param[out] subscr  place retrieved data in this struct.
 * \returns 0 on success, -ENOENT if no such subscriber was found, -EIO on
 *          database error.
 */
int db_subscr_get_by_id(struct db_context *dbc, int64_t id,
			struct hlr_subscriber *subscr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_SEL_BY_ID];
	const char *err;
	int rc;

	if (!db_bind_int64(stmt, NULL, id))
		return -EIO;

	rc = db_sel(dbc, stmt, subscr, &err);
	if (rc && rc != -ENOENT)
		LOGP(DAUC, LOGL_ERROR, "Cannot read subscriber from db: ID=%" PRId64 ": %s\n",
		     id, err);
	return rc;
}

/*! Retrieve subscriber data from the HLR database.
 * \param[in,out] dbc  database context.
 * \param[in] imei  ASCII string of identifier digits
 * \param[out] subscr  place retrieved data in this struct.
 * \returns 0 on success, -ENOENT if no such subscriber was found, -EIO on
 *          database error.
 */
int db_subscr_get_by_imei(struct db_context *dbc, const char *imei, struct hlr_subscriber *subscr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_SEL_BY_IMEI];
	const char *err;
	int rc;

	if (!db_bind_text(stmt, NULL, imei))
		return -EIO;

	rc = db_sel(dbc, stmt, subscr, &err);
	if (rc && rc != -ENOENT)
		LOGP(DAUC, LOGL_ERROR, "Cannot read subscriber from db: IMEI=%s: %s\n", imei, err);
	return rc;
}

/*! You should use hlr_subscr_nam() instead; enable or disable PS or CS for a
 * subscriber without notifying GSUP clients.
 * \param[in,out] dbc  database context.
 * \param[in] imsi  ASCII string of IMSI digits.
 * \param[in] nam_val True to enable CS/PS, false to disable.
 * \param[in] is_ps  when true, set nam_ps, else set nam_cs.
 * \returns 0 on success, -ENOENT when the given IMSI does not exist, -EIO on
 *          database errors.
 */
int db_subscr_nam(struct db_context *dbc, const char *imsi, bool nam_val, bool is_ps)
{
	sqlite3_stmt *stmt;
	int rc;
	int ret = 0;

	stmt = dbc->stmt[is_ps ? DB_STMT_UPD_NAM_PS_BY_IMSI
			       : DB_STMT_UPD_NAM_CS_BY_IMSI];

	if (!db_bind_text(stmt, "$imsi", imsi))
		return -EIO;
	if (!db_bind_int(stmt, "$val", nam_val ? 1 : 0))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGHLR(imsi, LOGL_ERROR, "%s %s: SQL error: %s\n",
		       nam_val ? "enable" : "disable",
		       is_ps ? "PS" : "CS",
		       sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot %s %s: no such subscriber: IMSI='%s'\n",
		     nam_val ? "enable" : "disable",
		     is_ps ? "PS" : "CS",
		     imsi);
		ret = -ENOENT;
		goto out;
	} else if (rc != 1) {
		LOGHLR(imsi, LOGL_ERROR, "%s %s: SQL modified %d rows (expected 1)\n",
		       nam_val ? "enable" : "disable",
		       is_ps ? "PS" : "CS",
		       rc);
		ret = -EIO;
	}

out:
	db_remove_reset(stmt);
	return ret;
}

/*! Record a Location Updating in the database.
 * \param[in,out] dbc  database context.
 * \param[in] subscr_id  ID of the subscriber in the HLR db.
 * \param[in] vlr_or_sgsn_number  ASCII string of identifier digits.
 * \param[in] is_ps  when true, set sgsn_number, else set vlr_number.
 * \returns 0 on success, -ENOENT when the given subscriber does not exist,
 *         -EIO on database errors.
 */
int db_subscr_lu(struct db_context *dbc, int64_t subscr_id,
		 const struct osmo_ipa_name *vlr_name, bool is_ps,
		 const struct osmo_ipa_name *via_proxy)
{
	sqlite3_stmt *stmt;
	int rc, ret = 0;
	struct timespec localtime;

	stmt = dbc->stmt[is_ps ? DB_STMT_UPD_SGSN_BY_ID
			       : DB_STMT_UPD_VLR_BY_ID];

	if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
		return -EIO;

	if (!db_bind_text(stmt, "$number", (char*)vlr_name->val))
		return -EIO;

	if (via_proxy && via_proxy->len) {
		if (!db_bind_text(stmt, "$proxy", (char*)via_proxy->val))
			return -EIO;
	} else {
		if (!db_bind_null(stmt, "$proxy"))
			return -EIO;
	}

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR, "Update %s number for subscriber ID=%" PRId64 ": SQL Error: %s\n",
		     is_ps? "SGSN" : "VLR", subscr_id, sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot update %s number for subscriber ID=%" PRId64
		     ": no such subscriber\n",
		     is_ps? "SGSN" : "VLR", subscr_id);
		ret = -ENOENT;
		goto out;
	} else if (rc != 1) {
		LOGP(DAUC, LOGL_ERROR, "Update %s number for subscriber ID=%" PRId64
		       ": SQL modified %d rows (expected 1)\n",
		       is_ps? "SGSN" : "VLR", subscr_id, rc);
		ret = -EIO;
		goto out;
	}

	db_remove_reset(stmt);

	if (osmo_clock_gettime(CLOCK_REALTIME, &localtime) != 0) {
		LOGP(DAUC, LOGL_ERROR, "Cannot get the current time: (%d) %s\n", errno, strerror(errno));
		ret = -errno;
		goto out;
	}

	stmt = dbc->stmt[is_ps? DB_STMT_SET_LAST_LU_SEEN_PS : DB_STMT_SET_LAST_LU_SEEN];

	if (!db_bind_int64(stmt, "$subscriber_id", subscr_id))
		return -EIO;
	/* The timestamp will be converted to UTC by SQLite. */
	if (!db_bind_int64(stmt, "$val", (int64_t)localtime.tv_sec)) {
		ret = -EIO;
		goto out;
	}

	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR,
		       "Cannot update LU timestamp for subscriber ID=%" PRId64 ": SQL error: (%d) %s\n",
		       subscr_id, rc, sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot update LU timestamp for subscriber ID=%" PRId64
		     ": no such subscriber\n", subscr_id);
		ret = -ENOENT;
		goto out;
	} else if (rc != 1) {
		LOGP(DAUC, LOGL_ERROR, "Update LU timestamp for subscriber ID=%" PRId64
		     ": SQL modified %d rows (expected 1)\n", subscr_id, rc);
		ret = -EIO;
	}
out:
	db_remove_reset(stmt);
	return ret;
}

/*! Set the ms_purged_cs or ms_purged_ps values in the database.
 * \param[in,out] dbc  database context.
 * \param[in] by_imsi  ASCII string of IMSI digits.
 * \param[in] purge_val  true to purge, false to un-purge.
 * \param[in] is_ps  when true, set ms_purged_ps, else set ms_purged_cs.
 * \returns 0 on success, -ENOENT when the given IMSI does not exist, -EIO on
 *          database errors.
 */
int db_subscr_purge(struct db_context *dbc, const char *by_imsi,
		    bool purge_val, bool is_ps)
{
	sqlite3_stmt *stmt;
	int rc, ret = 0;

	stmt = dbc->stmt[is_ps ? DB_STMT_UPD_PURGE_PS_BY_IMSI
			       : DB_STMT_UPD_PURGE_CS_BY_IMSI];

	if (!db_bind_text(stmt, "$imsi", by_imsi))
		return -EIO;
	if (!db_bind_int(stmt, "$val", purge_val ? 1 : 0))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (rc != SQLITE_DONE) {
		LOGP(DAUC, LOGL_ERROR, "%s %s: SQL error: %s\n",
		     purge_val ? "purge" : "un-purge",
		     is_ps ? "PS" : "CS",
		     sqlite3_errmsg(dbc->db));
		ret = -EIO;
		goto out;
	}

	/* verify execution result */
	rc = sqlite3_changes(dbc->db);
	if (!rc) {
		LOGP(DAUC, LOGL_ERROR, "Cannot %s %s: no such subscriber: IMSI='%s'\n",
		     purge_val ? "purge" : "un-purge",
		     is_ps ? "PS" : "CS",
		     by_imsi);
		ret = -ENOENT;
		goto out;
	} else if (rc != 1) {
		LOGHLR(by_imsi, LOGL_ERROR, "%s %s: SQL modified %d rows (expected 1)\n",
		       purge_val ? "purge" : "un-purge",
		       is_ps ? "PS" : "CS",
		       rc);
		ret = -EIO;
	}

out:
	db_remove_reset(stmt);

	return ret;
}

static int _db_ind_run(struct db_context *dbc, sqlite3_stmt *stmt, const char *vlr, bool reset)
{
	int rc;

	if (!db_bind_text(stmt, "$vlr", vlr))
		return -EIO;

	/* execute the statement */
	rc = sqlite3_step(stmt);
	if (reset)
		db_remove_reset(stmt);
	return rc;
}

static int _db_ind_add(struct db_context *dbc, const char *vlr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_ADD];
	if (_db_ind_run(dbc, stmt, vlr, true) != SQLITE_DONE) {
		LOGP(DDB, LOGL_ERROR, "Cannot create IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr, -1));
		return -EIO;
	}
	return 0;
}

static int _db_ind_del(struct db_context *dbc, const char *vlr)
{
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_DEL];
	_db_ind_run(dbc, stmt, vlr, true);
	/* We don't really care about the result. If it didn't exist, then that was the goal anyway. */
	return 0;
}

static int _db_ind_get(struct db_context *dbc, const char *vlr, unsigned int *ind)
{
	int ret = 0;
	sqlite3_stmt *stmt = dbc->stmt[DB_STMT_IND_SELECT];
	int rc = _db_ind_run(dbc, stmt, vlr, false);
	if (rc == SQLITE_DONE) {
		/* Does not exist yet */
		ret = -ENOENT;
		goto out;
	} else if (rc != SQLITE_ROW) {
		LOGP(DDB, LOGL_ERROR, "Error executing SQL: %d\n", rc);
		ret = -EIO;
		goto out;
	}

	OSMO_ASSERT(ind);
	*ind = sqlite3_column_int64(stmt, 0);
out:
	db_remove_reset(stmt);
	return ret;
}

int _db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr,
	    unsigned int *ind, bool del)
{
	const char *vlr_name = NULL;
	int rc;

	switch (vlr->type) {
	case OSMO_CNI_PEER_ID_IPA_NAME:
		if (vlr->ipa_name.len < 2 || vlr->ipa_name.val[vlr->ipa_name.len - 1] != '\0') {
			LOGP(DDB, LOGL_ERROR, "Expecting VLR ipa_name to be zero terminated; found %s\n",
			     osmo_ipa_name_to_str(&vlr->ipa_name));
			return -ENOTSUP;
		}
		vlr_name = (const char*)vlr->ipa_name.val;
		break;
	default:
		LOGP(DDB, LOGL_ERROR, "Unsupported osmo_cni_peer_id type: %s\n",
		     osmo_cni_peer_id_type_name(vlr->type));
		return -ENOTSUP;
	}

	if (del)
		return _db_ind_del(dbc, vlr_name);

	rc = _db_ind_get(dbc, vlr_name, ind);
	if (!rc)
		return 0;

	/* Does not exist yet, create. */
	rc = _db_ind_add(dbc, vlr_name);
	if (rc) {
		LOGP(DDB, LOGL_ERROR, "Error creating IND entry for %s\n", osmo_quote_str_c(OTC_SELECT, vlr_name, -1));
		return rc;
	}

	/* To be sure, query again from scratch. */
	return _db_ind_get(dbc, vlr_name, ind);
}

int db_ind(struct db_context *dbc, const struct osmo_cni_peer_id *vlr, unsigned int *ind)
{
	return _db_ind(dbc, vlr, ind, false);
}

int db_ind_del(struct db_context *dbc, const struct osmo_cni_peer_id *vlr)
{
	return _db_ind(dbc, vlr, NULL, true);
}
