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

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

	idiscovery "v.io/x/ref/lib/discovery"
)

func (d *gdiscovery) Advertise(ctx *context.T, ad *discovery.Advertisement, visibility []security.BlessingPattern) (<-chan struct{}, error) {
	if !ad.Id.IsValid() {
		var err error
		if ad.Id, err = discovery.NewAdId(); err != nil {
			return nil, err
		}
	}
	if err := validateAd(ad); err != nil {
		return nil, idiscovery.NewErrBadAdvertisement(ctx, err)
	}
	if len(visibility) == 0 {
		visibility = []security.BlessingPattern{security.AllPrincipals}
	}

	principal := v23.GetPrincipal(ctx)
	self := security.DefaultBlessingPatterns(principal)
	perms := access.Permissions{
		string(access.Admin): access.AccessList{In: self},
		string(access.Read):  access.AccessList{In: visibility},
	}

	if !d.addAd(ad) {
		return nil, idiscovery.NewErrAlreadyBeingAdvertised(ctx, ad.Id)
	}

	// TODO(jhahn): There is no atomic way to check and reserve the name under mounttable.
	// For example, the name can be overwritten by other applications of the same owner.
	// But this would be OK for now.
	name := ad.Id.String()
	if err := d.ns.SetPermissions(ctx, name, perms, "", naming.IsLeaf(true)); err != nil {
		d.removeAd(ad)
		return nil, err
	}

	// TODO(jhahn): We're using one goroutine per advertisement, but we can do
	// better like have one goroutine that takes care of all advertisements.
	// But this is OK for now as an experiment.
	done := make(chan struct{})
	go func() {
		defer close(done)
		defer d.removeAd(ad)
		// We need a context that is detached from the deadlines and cancellation
		// of ctx since we have to unmount after ctx is canceled.
		rctx, _ := context.WithRootCancel(ctx)
		defer d.unmount(rctx, name)

		for {
			d.mount(ctx, name, ad.Addresses)

			select {
			case <-d.clock.After(d.mountTTL):
			case <-ctx.Done():
				return
			}
		}
	}()
	return done, nil
}

func (d *gdiscovery) addAd(ad *discovery.Advertisement) bool {
	d.mu.Lock()
	if _, exist := d.ads[ad.Id]; exist {
		d.mu.Unlock()
		return false
	}
	d.ads[ad.Id] = struct{}{}
	d.mu.Unlock()
	return true
}

func (d *gdiscovery) removeAd(ad *discovery.Advertisement) {
	d.mu.Lock()
	delete(d.ads, ad.Id)
	d.mu.Unlock()
}

func (d *gdiscovery) mount(ctx *context.T, name string, addrs []string) {
	for _, addr := range addrs {
		if err := d.ns.Mount(ctx, name, addr, d.mountTTLWithSlack); err != nil {
			ctx.Errorf("mount(%q, %q) failed: %v", name, addr, err)
		}
	}
}

func (d *gdiscovery) unmount(ctx *context.T, name string) {
	if err := d.ns.Delete(ctx, name, true); err != nil {
		ctx.Infof("unmount(%q) failed: %v", name, err)
	}
}
