// 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;
using zx;

/// Primary mDNS service interface.
///
/// In mDNS, all strings are UTF-8 encoded and limited to 255 bytes, not
/// including null termination. Host, service and instance names consist of
/// labels separated by '.'. Labels are limited to 63 bytes not including the
/// separator.
[Discoverable]
protocol Controller {
    /// Gets the addresses for the specified host name. `host_name` may not end
    /// in a '.'. `timeout` specifies how long the service should wait before
    /// giving up when waiting for a response to a resolution query. In typical
    /// use, a timeout of two or three seconds is recommended.
    ///
    /// A successful resolution may return one or both addresses. An
    /// unsuccessful resolution is indicated when both addresses are null.
    ResolveHostName(string:255 host_name, zx.duration timeout)
        -> (fuchsia.netstack.SocketAddress? v4_address,
            fuchsia.netstack.SocketAddress? v6_address);

    /// Subscribes to a service. The subscription lasts until `subscriber` is
    /// unbound. `service_name` must end in '._tcp.' or '._udp.'.
    SubscribeToService(string:255 service_name, ServiceSubscriber subscriber);

    /// Publishes a service instance. `service_name` must end in '._tcp.' or
    /// '._udp.'. `instance_name` must not end in a '.'. `responder` is
    /// consulted via its `GetPublication` method 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`. `perform_probe` indicates whether a probe for a
    /// conflicting instance should be performed before publishing the instance.
    /// This value should be `true` unless the instance name is known to be
    /// unique.
    PublishServiceInstance(string:255 service_name,
                           string:255 instance_name,
                           bool perform_probe,
                           Responder responder) -> (Result result);

    /// Publishes a service instance available at the specified port. The
    /// service instance 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.
    /// `perform_probe` indicates whether a probe for a conflicting instance
    /// should be performed before publishing the instance. This value should
    /// be `true` unless the instance name is known to be unique.
    // TODO(NET-2188): Remove this after implementing config files.
    DEPRECATEDPublishServiceInstance(string:255 service_name,
                                     string:255 instance_name,
                                     uint16 port,
                                     vector<string:255> text,
                                     bool perform_probe) -> (Result result);

    /// Ends publication started with `PublishServiceInstance`. `service_name`
    /// must end in '._tcp.' or '._udp.'. `instance_name` must not end in a '.'.
    // TODO(NET-2188): Remove this after implementing config files.
    DEPRECATEDUnpublishServiceInstance(string:255 service_name,
                                       string:255 instance_name);

    /// Specifies whether mDNS traffic should be logged.
    // TODO(NET-2189): Move to /hub.
    DEPRECATEDSetVerbose(bool value);
};

/// Result values for instance publishing.
// TODO(dalesat): Rename 'Error' and use error syntax when generally available.
enum Result : int32 {
    /// Operation succeeded.
    OK = 0;

    /// The specified service name is invalid.
    INVALID_SERVICE_NAME = -1;

    /// The specified instance name is invalid.
    INVALID_INSTANCE_NAME = -2;

    /// The specified service instance is already being published by this
    /// mDNS implementation.
    ALREADY_PUBLISHED_LOCALLY = -3;

    /// The specified service instance is already being published by another
    /// host on the subnet. This result occurs when an initial probe discovers
    /// a conflicting instance.
    ALREADY_PUBLISHED_ON_SUBNET = -4;
};

/// Client-implemented interface for subscribers. Method replies are used to
/// throttle traffic. The service won't necessarily wait for a reply before
/// calling another method.
protocol ServiceSubscriber {
    /// Notifies the subscriber that a service instance has been discovered.
    InstanceDiscovered(ServiceInstance instance) -> ();

    /// Notifies the subscriber that addresses or text for a known service
    /// instance have changed.
    InstanceChanged(ServiceInstance instance) -> ();

    /// Notifies the subscriber that a known service instance has been lost.
    InstanceLost(string:255 service_name, string:255 instance_name) -> ();
};

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

/// Client-supplied responder interface.
protocol Responder {
    /// Provides instance information for initial announcements and query
    /// responses relating to the service instance specified in
    /// `Controller.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:255? subtype)
        -> (Publication? publication);

    /// Sets the subtypes for the service instance. The specified subtypes will
    /// be announced subject to filtering through the `Responder`. The initial
    /// subtype collection is empty.
    -> OnSubtypesChanged(vector<string:255> subtypes);

    /// Initiates reannouncement of the service instance due to a change in the
    /// instance's port number or text strings. All announcements are filtered
    /// through `GetPublication`, which replies with the new port and text
    /// values.
    -> OnPublicationChanged();
};

/// Describes an initial instance announcement or query response. `port` is
/// host-endian. In typical use, the default TTL values should be used. TTL
/// values are rounded down to the nearest second. TTL values less than one
/// second are not permitted and will result in the `Responder` channel being
/// closed.
struct Publication {
    uint16 port;
    vector<string:255> text;
    zx.duration ptr_ttl = 4500000000000; // default 75 minutes
    zx.duration srv_ttl = 120000000000; // default 2 minutes
    zx.duration txt_ttl = 4500000000000; // default 75 minutes
};
