// 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 (
	"sync"

	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/verror"
)

const pkgPath = "v.io/x/ref/runtime/internal/discovery"


var (
	errDiscoveryClosed = verror.Register(pkgPath+".errDiscoveryClosed", verror.NoRetry, "{1:}{2:} discovery closed")
)

// ds is an implementation of discovery.T.
type ds struct {
	plugins []Plugin

	mu     sync.Mutex
	closed bool                  // GUARDED_BY(mu)
	tasks  map[*context.T]func() // GUARDED_BY(mu)
	wg     sync.WaitGroup

	ads map[string]struct{} // GUARDED_BY(mu)
}

func (ds *ds) Close() {
	ds.mu.Lock()
	if ds.closed {
		ds.mu.Unlock()
		return
	}
	for _, cancel := range ds.tasks {
		cancel()
	}
	ds.closed = true
	ds.mu.Unlock()
	ds.wg.Wait()
}

func (ds *ds) addTask(ctx *context.T) (*context.T, func(), error) {
	ds.mu.Lock()
	if ds.closed {
		ds.mu.Unlock()
		return nil, nil, verror.New(errDiscoveryClosed, ctx)
	}
	ctx, cancel := context.WithCancel(ctx)
	ds.tasks[ctx] = cancel
	ds.wg.Add(1)
	ds.mu.Unlock()
	return ctx, cancel, nil
}

func (ds *ds) removeTask(ctx *context.T) {
	ds.mu.Lock()
	if _, exist := ds.tasks[ctx]; exist {
		delete(ds.tasks, ctx)
		ds.wg.Done()
	}
	ds.mu.Unlock()
}

// New returns a new Discovery instance initialized with the given plugins.
//
// Mostly for internal use. Consider to use factory.New.
func NewWithPlugins(plugins []Plugin) discovery.T {
	if len(plugins) == 0 {
		panic("no plugins")
	}
	ds := &ds{
		plugins: make([]Plugin, len(plugins)),
		tasks:   make(map[*context.T]func()),
		ads:     make(map[string]struct{}),
	}
	copy(ds.plugins, plugins)
	return ds
}
