module discovery;

// Copied from v.io/v23/discovery/types.vdl
struct Service {
    // The 128 bit (16 byte) universal unique identifier of a service instance.
	// If this is not specified, a random UUID will be used.
	array<uint8> InstanceUuid;
	// The interface that the service implements.
	// E.g., 'v.io/v23/services/vtrace.Store'.
	string InterfaceName;
	// The service attributes.
	// E.g., {'resolution': '1024x768'}.
	map<string, string> Attrs;
	// The addresses that the service is served on.
	// E.g., '/host:port/a/b/c'.
	array<string> Addrs;
};

struct Error {
   string id;
   int32 action;
   string msg;
};

// Advertiser provides methods to do Vanadium Advertising.
interface Advertiser {
	// Advertises the given Service to all blessings that match pattern.  Returns
	// a handle to the active advertisement that can be used to stop the advertisement.
	Advertise(Service s, array<string> pattern) => (int32 Handle, Error? Err);

	// StopAdvertising Stops the advertisement associated with the given handle.
	StopAdvertising(int32 h);
};

// Scanner provides methods to scan for Vanadium advertisements.
interface Scanner {
	// Scan scans for services matching the query passed nad calls ScanHandler with updates.
	// Returns a handle to the active scanner that can be used to stop the scanning.
	Scan(string query, ScanHandler scanHandler) => (int32 Handle, Error? Err);

	// StopScan stops the scanner associated weith the given handle.
	StopScan(int32 h);
};

// ScanHandler is used to pass updates about Services that are found/lost during the
// scan.
interface ScanHandler {
	// Found will be called when a Service is found.
	Found(Service s);

	// Lost will be called when a service is lost.
	Lost(Service s);
};