// 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 discovery

import (
	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
)

// AdvertiseServer advertises the server with the given advertisement. It uses
// the server's endpoints and the given suffix as the advertisement addresses,
// and the addresses will be updated automatically when the underlying network
// are changed.
//
// The advertisement should not be changed while it is being advertised.
//
// Advertising will continue until the context is canceled or exceeds its deadline
// and the returned channel will be closed when it stops.
//
// If a discovery instance is not provided, this will create a new one.
func AdvertiseServer(ctx *context.T, d discovery.T, server rpc.Server, suffix string, ad *discovery.Advertisement, visibility []security.BlessingPattern) (<-chan struct{}, error) {
	if d == nil {
		var err error
		d, err = v23.NewDiscovery(ctx)
		if err != nil {
			return nil, err
		}
	}

	status := server.Status()
	curAddrs := sortedNames(status.Endpoints)
	stop, err := advertiseServer(ctx, d, ad, curAddrs, suffix, visibility)
	if err != nil {
		return nil, err
	}

	done := make(chan struct{})
	go func() {
		defer close(done)

		for {
			select {
			case <-status.Dirty:
				status = server.Status()
				if status.State != rpc.ServerActive {
					return
				}
				newAddrs := sortedNames(status.Endpoints)
				if sortedStringsEqual(curAddrs, newAddrs) {
					continue
				}

				stop() // Stop the previous advertisement.
				stop, err = advertiseServer(ctx, d, ad, newAddrs, suffix, visibility)
				if err != nil {
					ctx.Error(err)
					return
				}
				curAddrs = newAddrs
			case <-ctx.Done():
				return
			}
		}
	}()
	return done, nil
}

func advertiseServer(ctx *context.T, d discovery.T, ad *discovery.Advertisement, addrs []string, suffix string, visibility []security.BlessingPattern) (func(), error) {
	ad.Addresses = make([]string, len(addrs))
	for i, addr := range addrs {
		ad.Addresses[i] = naming.JoinAddressName(addr, suffix)
	}
	ctx, cancel := context.WithCancel(ctx)
	done, err := d.Advertise(ctx, ad, visibility)
	if err != nil {
		cancel()
		return nil, err
	}
	stop := func() {
		cancel()
		<-done
	}
	return stop, nil
}
