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

package io.v.v23.rpc;

import io.v.v23.verror.VException;

import java.util.Arrays;

/**
 * Stores the information required to create a listening network endpoint for a server
 * and, optionally, the name of a proxy to use in conjunction with that listener.
 */
public class ListenSpec {
    /**
     * A pair of (network protocol, address) that the server should listen on.
     * For TCP, the address must be in {@code ip:port} format. The {@code ip} may be omitted, but
     * the {@code port} can not (choose a port of {@code 0} to have the system allocate one).
     */
    public static class Address {
        private final String protocol;
        private final String address;

        /**
         * Creates a new {@link Address} with the given protocol and address.
         *
         * @param  protocol network protocol (e.g., {@code "tcp"})
         * @param  address  network address (e.g., {@code "localhost:32786"})
         */
        public Address(String protocol, String address) {
            this.protocol = protocol;
            this.address = address;
        }

        /**
         * Returns the network protocol.
         */
        public String getProtocol() { return this.protocol; }

        /**
         * Returns the network address.
         */
        public String getAddress() { return this.address; }

        @Override
        public String toString() {
            return this.protocol + ":" + this.address;
        }
    }

    private final Address[] addrs;  // non-null
    private final String proxy;  // non-null
    private final AddressChooser chooser;  // non-null

    /**
     * Creates a new {@link ListenSpec} with the given addresses, proxy,
     * and {@link AddressChooser}.
     *
     * @param  addrs   {@link Address}es that the server should listen on
     * @param  proxy   proxy that the server should use to proxy the connection
     * @param  chooser {@link AddressChooser} used for selecting addresses to publish with the
     *                 mount table from a candidate set of addresses;  if {@code null}, a default
     *                 {@link AddressChooser} that chooses all the addresses will be used.
     */
    public ListenSpec(Address[] addrs, String proxy, AddressChooser chooser) {
        this.addrs = addrs == null ? new Address[0] : Arrays.copyOf(addrs, addrs.length);
        this.proxy = proxy == null ? "" : proxy;
        this.chooser = chooser != null ? chooser : new AddressChooser() {
            @Override
            public NetworkAddress[] choose(String protocol, NetworkAddress[] candidates)
                    throws VException {
                return candidates;
            }
        };
    }

    /**
     * Same as {@link #ListenSpec(Address[],String,AddressChooser)}, only with a
     * single listening {@link Address}.
     */
    public ListenSpec(Address addr, String proxy, AddressChooser chooser) {
        this(new Address[]{ addr }, proxy, chooser);
    }

    /**
     * Returns a new copy of this {@link ListenSpec} with the {@link AddressChooser} replaced with
     * the given address chooser.
     */
    public ListenSpec withAddressChooser(AddressChooser newChooser) {
        return new ListenSpec(getAddresses(), proxy, newChooser);
    }

    /**
     * Returns a new copy of this {@link ListenSpec} whose {@link #getProxy} method will return the
     * given proxy.
     */
    public ListenSpec withProxy(String newProxy) {
        return new ListenSpec(getAddresses(), newProxy, chooser);
    }

    /**
     * Returns a new copy of this {@link ListenSpec} whose {@link #getAddresses} method will return
     * an array containing only the given address.
     */
    public ListenSpec withAddress(Address address) {
        return new ListenSpec(new Address[]{address}, proxy, chooser);
    }

    /**
     * Returns the addresses the server should listen on.
     */
    public Address[] getAddresses() {
        return Arrays.copyOf(this.addrs, this.addrs.length);
    }

    /**
     * Returns the name of the proxy.  If empty, the server isn't proxied.
     */
    public String getProxy() { return this.proxy; }

    /**
     * Returns the address chooser that is used to choose the preferred address
     * to publish with the mount table when one is not otherwise specified.
     */
    public AddressChooser getChooser() { return this.chooser; }

    @Override
    public String toString() {
        return Arrays.toString(this.addrs) +
                (this.proxy.isEmpty() ? "" : "proxy(" + this.proxy + ")");
    }
}