// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

library fuchsia.mdns;

using fuchsia.netstack;

// Primary mDNS service interface.
[Discoverable]
interface Controller {
    // Gets the addresses for the specified host name. |host_name| may not end in
    // a '.'.
    ResolveHostName(string host_name, uint32 timeout_ms)
        -> (fuchsia.netstack.SocketAddress? v4_address,
            fuchsia.netstack.SocketAddress? v6_address);

    // Subscribes to a service. The subscription lasts until |subscription| is
    // unbound. |service_name| must end in '._tcp.' or '._udp.'.
    // TODO(dalesat): Replace request<ServiceSubscription> with ServiceSubscriber.
    SubscribeToService(string service_name,
                       request<ServiceSubscription> subscription);

    // Publishes a service instance available at the specified port. The service
    // is published until it is unpublished via |UnpublishServiceInstance|.
    // |service_name| must end in '._tcp.' or '._udp.'. |instance_name| must not
    // end in a '.'. |port| is host-endian. |text| contains metadata strings that
    // describe the instance. No subtypes are published unless the |SetSubtypes|
    // method is called.
    PublishServiceInstance(string service_name,
                           string instance_name,
                           uint16 port,
                           vector<string>? text) -> (Result result);

    // Ends publication started with |PublishServiceInstance|. |service_name| must
    // end in '._tcp.' or '._udp.'. |instance_name| must not end in a '.'.
    UnpublishServiceInstance(string service_name, string instance_name);

    // Publishes a service instance with support for subtypes. |service_name| must
    // end in '._tcp.' or '._udp.'. |instance_name| must not end in a '.'.
    // |responder| is consulted for initial announcements and to answer queries.
    // The service is published until the |responder| channel closes. In addition
    // to announcements and queries for the service type, all queries for subtypes
    // are answered subject to filtering through the |Responder|. If subtype
    // announcement is desired, a call to |SetSubtypes| is required to set the
    // list of announced subtypes.
    AddResponder(string service_name,
                 string instance_name,
                 Responder responder);

    // Sets the subtypes for a service instance currently being published due to
    // a call to |PublishServiceInstance| or |AddResponder|.  |service_name| must
    // end in '._tcp.' or '._udp.'. |instance_name| must not end in a '.'. For an
    // instance published with |PublishServiceInstance|, the specified subtypes
    // will be announced, and queries for the subtypes will be answered. For an
    // instance published with |AddResponder|, the specified subtypes will be
    // announced subject to filtering through the |Responder|. All subtype
    // queries are forwarded to the |Responder|, so this method has no effect
    // in that regard.
    SetSubtypes(string service_name,
                string instance_name,
                vector<string> subtypes);

    // Initiates announcement of a service instance currently being published due
    // to a call to |PublishServiceInstance| or |AddResponder|. This is generally
    // not needed for the |PublishServiceInstance| case. For instances published
    // with |AddResponder|, this method is typically used when the port or text
    // associated with the instance changes. All announcements are filtered
    // through the |Responder|, which can reply with the new port and text
    // values.
    ReannounceInstance(string service_name, string instance_name);

    // Specifies whether mDNS traffic should be logged.
    SetVerbose(bool value);
};

// Result values for instance publishing.
enum Result : int32 {
    OK = 0;
    INVALID_SERVICE_NAME = -1;
    INVALID_INSTANCE_NAME = -2;
    ALREADY_PUBLISHED_LOCALLY = -3;
    ALREADY_PUBLISHED_ON_SUBNET = -4;
};

// Special value for GetInstances version_last_seen parameter to get the
// current instances immediately.
const uint64 kInitialInstances = 0;

// Represents a subscription.
// TODO(dalesat): Replace this with ServiceSubscriber, a client-implemented
// interface that is not susceptible to channel overrun.
interface ServiceSubscription {
    // Gets the known service instances. To get the list immediately, call
    // |GetInstances(kInitialInstances)|. To get updates thereafter, pass the
    // version sent in the previous callback.
    GetInstances(uint64 version_last_seen)
        -> (uint64 version, vector<ServiceInstance> instances);
};

// Describes a service instance.
struct ServiceInstance {
    string service_name;
    string instance_name;
    fuchsia.netstack.SocketAddress? v4_address;
    fuchsia.netstack.SocketAddress? v6_address;
    vector<string>? text;
};

// Client-supplied responder interface.
interface Responder {
    // Updates the status of the instance publication.
    UpdateStatus(Result result);

    // Provides instance information for initial announcements and query responses
    // relating to the service instance specified in |Service.AddResponder|.
    // |query| indicates whether data is requested for an initial announcement
    // (false) or in response to a query (true). If the publication relates to a
    // subtype of the service, |subtype| contains the subtype, otherwise it is
    // null. If |publication| is null, no announcement or response is transmitted.
    // Strings in |text| are transmitted in the TXT record.
    GetPublication(bool query, string? subtype)
        -> (Publication? publication);
};

// Describes an initial instance publication or query response. |port| is host-
// endian.
struct Publication {
    uint16 port;
    vector<string>? text;
    uint32 ptr_ttl_seconds = 4500; // default 75 minutes
    uint32 srv_ttl_seconds = 120; // default 2 minutes
    uint32 txt_ttl_seconds = 4500; // default 75 minutes
};
