/* 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 General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/mslookup/mslookup.h>

struct osmo_mslookup_client;
struct osmo_mslookup_result;

typedef void (*osmo_mslookup_cb_t)(struct osmo_mslookup_client *client,
				   uint32_t request_handle,
				   const struct osmo_mslookup_query *query,
				   const struct osmo_mslookup_result *result);

/*! This handling information is passed along with a lookup request.
 * It tells the osmo_mslookup_client layer how to handle responses received from various mslookup methods (at the time
 * of writing only mDNS exists as a method, but the intention is to easily allow adding other methods in the future).
 * This query handling info is not seen by the individual method implementations, to clarify that it is the
 * osmo_mslookup_client layer that takes care of these details. */
struct osmo_mslookup_query_handling {
	/*! Wait at least this long before returning any results.
	 *
	 * If nonzero, result_cb will be called as soon as this delay has elapsed, either with the so far youngest age
	 * result, or with a "not found yet" result. After this delay has elapsed, receiving results will continue
	 * until result_timeout_milliseconds has elapsed.
	 *
	 * If zero, responses are fed to the result_cb right from the start, every time a younger aged result than
	 * before comes in.
	 *
	 * If a result with age == 0 is received, min_wait_milliseconds is ignored, the result is returned immediately
	 * and listening for responses ends.
	 *
	 * Rationale: If a subscriber has recently moved between sites, multiple results will arrive, and the youngest
	 * age wins. It can make sense to wait a minimum time for responses before determining the winning result.
	 *
	 * However, if no result or no valid result has arrived within a short period, the subscriber may be at a site
	 * that is far away or that is currently experiencing high latency. It is thus a good safety net to still
	 * receive results for an extended period of time.
	 *
	 * For some services, it is possible to establish links to every received result, and whichever link succeeds
	 * will be used (for example for SIP calls: first to pick up the call gets connected, the others are dropped
	 * silently).
	 */
	uint32_t min_wait_milliseconds;

	/*! Total time in milliseconds to listen for lookup responses.
	 *
	 * When this timeout elapses, osmo_mslookup_client_request_cancel() is called implicitly; Manually invoking
	 * osmo_mslookup_client_request_cancel() after result_timeout_milliseconds has elapsed is not necessary, but is
	 * still safe to do anyway.
	 *
	 * If zero, min_wait_milliseconds is also used as result_timeout_milliseconds; if that is also zero, a default
	 * timeout value is used.
	 *
	 * If result_timeout_milliseconds <= min_wait_milliseconds, then min_wait_milliseconds is used as
	 * result_timeout_milliseconds, i.e. the timeout triggers as soon as min_wait_milliseconds hits.
	 *
	 * osmo_mslookup_client_request_cancel() can be called any time to end the request.
	 */
	uint32_t result_timeout_milliseconds;

	/*! Invoked every time a result with a younger age than the previous result has arrived.
	 * To stop receiving results before result_timeout_milliseconds has elapsed, call
	 * osmo_mslookup_client_request_cancel().
	 */
	osmo_mslookup_cb_t result_cb;
};

uint32_t osmo_mslookup_client_request(struct osmo_mslookup_client *client,
				      const struct osmo_mslookup_query *query,
				      const struct osmo_mslookup_query_handling *handling);

void osmo_mslookup_client_request_cancel(struct osmo_mslookup_client *client, uint32_t request_handle);

struct osmo_mslookup_client *osmo_mslookup_client_new(void *ctx);
bool osmo_mslookup_client_active(struct osmo_mslookup_client *client);
void osmo_mslookup_client_free(struct osmo_mslookup_client *client);

/*! Describe a specific mslookup client method implementation. This struct is only useful for a lookup method
 * implementation to add itself to an osmo_mslookup_client, see for example osmo_mslookup_client_add_mdns(). */
struct osmo_mslookup_client_method {
	struct llist_head entry;

	/*! Human readable name of this lookup method. */
	const char *name;

	/*! Private data for the lookup method implementation. */
	void *priv;

	/*! Backpointer to the client this method is added to. */
	struct osmo_mslookup_client *client;

	/*! Launch a lookup query. Called from osmo_mslookup_client_request().
	 * The implementation returns results by calling osmo_mslookup_client_rx_result(). */
	void (*request)(struct osmo_mslookup_client_method *method,
			const struct osmo_mslookup_query *query,
			uint32_t request_handle);
	/*! End a lookup query. Called from osmo_mslookup_client_request_cancel(). It is guaranteed to be called
	 * exactly once per above request() invocation. (The API user is required to invoke
	 * osmo_mslookup_client_request_cancel() exactly once per osmo_mslookup_client_request().) */
	void (*request_cleanup)(struct osmo_mslookup_client_method *method,
				uint32_t request_handle);

	/*! The mslookup_client is removing this method, clean up all open requests, lists and allocations. */
	void (*destruct)(struct osmo_mslookup_client_method *method);
};

void osmo_mslookup_client_method_add(struct osmo_mslookup_client *client,
				     struct osmo_mslookup_client_method *method);
bool osmo_mslookup_client_method_del(struct osmo_mslookup_client *client,
				     struct osmo_mslookup_client_method *method);
void osmo_mslookup_client_rx_result(struct osmo_mslookup_client *client, uint32_t request_handle,
				    const struct osmo_mslookup_result *result);
