/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 *
 * 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 <sys/time.h>
#include <string.h>
#include <osmocom/core/application.h>
#include <osmocom/core/select.h>
#include <osmocom/hlr/logging.h>
#include <osmocom/mslookup/mslookup_client_fake.h>
#include <osmocom/mslookup/mslookup_client.h>

#define SERVICE_HLR_GSUP "gsup.hlr"
#define SERVICE_SIP "sip.voice"

void *ctx = NULL;

static struct osmo_mslookup_fake_response fake_lookup_responses[] = {
	{
		.time_to_reply = { .tv_sec = 1, },
		.for_id = {
			.type = OSMO_MSLOOKUP_ID_IMSI,
			.imsi = "1234567",
		},
		.for_service = SERVICE_HLR_GSUP,
		.result = {
			.rc = OSMO_MSLOOKUP_RC_RESULT,
			.host_v4 = {
				.af = AF_INET,
				.ip = "12.34.56.7",
				.port = 42,
			},
			.host_v6 = {
				.af = AF_INET6,
				.ip = "be:ef:ed:ca:fe:fa:ce::1",
				.port = 42,
			},
			.age = 0,
		},
	},
	{
		.time_to_reply = { .tv_usec = 600 * 1000, },
		.for_id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "112",
		},
		.for_service = SERVICE_SIP,
		.result = {
			.rc = OSMO_MSLOOKUP_RC_RESULT,
			.host_v4 = {
				.af = AF_INET,
				.ip = "66.66.66.66",
				.port = 666,
			},
			.host_v6 = {
				.af = AF_INET,
				.ip = "6666:6666:6666::6",
				.port = 666,
			},
			.age = 423,
		},
	},
	{
		.time_to_reply = { .tv_usec = 800 * 1000, },
		.for_id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "112",
		},
		.for_service = SERVICE_SIP,
		.result = {
			.rc = OSMO_MSLOOKUP_RC_RESULT,
			.host_v4 = {
				.af = AF_INET,
				.ip = "112.112.112.112",
				.port = 23,
			},
			.age = 235,
		},
	},
	{
		.time_to_reply = { .tv_sec = 1, .tv_usec = 200 * 1000, },
		.for_id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "112",
		},
		.for_service = SERVICE_SIP,
		.result = {
			.rc = OSMO_MSLOOKUP_RC_RESULT,
			.host_v4 = {
				.af = AF_INET,
				.ip = "99.99.99.99",
				.port = 999,
			},
			.host_v6 = {
				.af = AF_INET,
				.ip = "9999:9999:9999::9",
				.port = 999,
			},
			.age = 335,
		},
	},
	{
		.time_to_reply = { .tv_sec = 1, .tv_usec = 500 * 1000, },
		.for_id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "112",
		},
		.for_service = SERVICE_SIP,
		.result = {
			.rc = OSMO_MSLOOKUP_RC_RESULT,
			.host_v4 = {
				.af = AF_INET,
				.ip = "99.99.99.99",
				.port = 999,
			},
			.age = 999,
		},
	},
};

const struct timeval fake_time_start_time = { 0, 0 };

#define fake_time_passes(secs, usecs) do \
{ \
	struct timeval diff; \
	osmo_gettimeofday_override_add(secs, usecs); \
	osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
	timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
	LOGP(DMSLOOKUP, LOGL_DEBUG, "Total time passed: %d.%06d s\n", \
	       (int)diff.tv_sec, (int)diff.tv_usec); \
	osmo_timers_prepare(); \
	osmo_timers_update(); \
} while (0)

static void fake_time_start(void)
{
	struct timespec *clock_override;

	osmo_gettimeofday_override_time = fake_time_start_time;
	osmo_gettimeofday_override = true;
	clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
	OSMO_ASSERT(clock_override);
	clock_override->tv_sec = fake_time_start_time.tv_sec;
	clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000;
	osmo_clock_override_enable(CLOCK_MONOTONIC, true);
	fake_time_passes(0, 0);
}

static void result_cb_once(struct osmo_mslookup_client *client,
			   uint32_t request_handle,
			   const struct osmo_mslookup_query *query,
			   const struct osmo_mslookup_result *result)
{
	LOGP(DMSLOOKUP, LOGL_DEBUG, "result_cb(): %s\n", osmo_mslookup_result_name_c(ctx, query, result));
}

int main(int argc, char **argv)
{
	ctx = talloc_named_const(NULL, 0, "main");
	osmo_init_logging2(ctx, NULL);

	log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
	log_set_print_level(osmo_stderr_target, 0);
	log_set_print_category(osmo_stderr_target, 0);
	log_set_print_category_hex(osmo_stderr_target, 0);
	log_set_use_color(osmo_stderr_target, 0);
	log_set_category_filter(osmo_stderr_target, DMSLOOKUP, true, LOGL_DEBUG);

	fake_time_start();

	struct osmo_mslookup_client *client = osmo_mslookup_client_new(ctx);
	osmo_mslookup_client_add_fake(client, fake_lookup_responses, ARRAY_SIZE(fake_lookup_responses));

	/* Place some requests to be replied upon asynchronously */

	struct osmo_mslookup_query_handling handling = {
		.result_timeout_milliseconds = 1, /* set some timeout < min_wait_milliseconds */
		.min_wait_milliseconds = 2000,
		.result_cb = result_cb_once,
	};

	struct osmo_mslookup_query q1 = {
		.service = SERVICE_HLR_GSUP,
		.id = {
			.type = OSMO_MSLOOKUP_ID_IMSI,
			.imsi = "1234567",
		},
	};
	OSMO_ASSERT(osmo_mslookup_client_request(client, &q1, &handling));

	struct osmo_mslookup_query q2 = {
		.service = SERVICE_SIP,
		.id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "112",
		},
	};
	handling.min_wait_milliseconds = 3000;
	OSMO_ASSERT(osmo_mslookup_client_request(client, &q2, &handling));

	struct osmo_mslookup_query q3 = {
		.service = "smpp.sms",
		.id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "00000",
		},
	};
	handling.min_wait_milliseconds = 5000;
	OSMO_ASSERT(osmo_mslookup_client_request(client, &q3, &handling));

	struct osmo_mslookup_query q4 = {
		.service = SERVICE_HLR_GSUP,
		.id = {
			.type = OSMO_MSLOOKUP_ID_MSISDN,
			.msisdn = "666",
		},
	};
	handling.min_wait_milliseconds = 10000;
	uint32_t q4_handle;
	OSMO_ASSERT((q4_handle = osmo_mslookup_client_request(client, &q4, &handling)));

	while (osmo_gettimeofday_override_time.tv_sec < 6) {
		log_reset_context();
		fake_time_passes(0, 1e6 / 5);
	}

	osmo_mslookup_client_request_cancel(client, q4_handle);

	return 0;
}
