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

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

type idiscovery struct {
	plugins []Plugin

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

	adMu          sync.Mutex
	adTimestampNs int64                         // GUARDED_BY(adMu)
	adSessions    map[discovery.AdId]sessionId  // GUARDED_BY(adMu)
	adSubtasks    map[discovery.AdId]*adSubtask // GUARDED_BY(adMu)
	adStopTrigger *Trigger

	dirServer *dirServer

	statsPrefix string
}

var (
	statsMu  sync.Mutex
	statsIdx int
)

type sessionId uint64

type adSubtask struct {
	parent *context.T

	mu   sync.Mutex
	stop func() // GUARDED_BY(mu)
}

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

	for _, plugin := range d.plugins {
		plugin.Close()
	}
}

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

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

func (d *idiscovery) cancelTask(ctx *context.T) {
	d.mu.Lock()
	cancel := d.tasks[ctx]
	d.mu.Unlock()
	if cancel != nil {
		cancel()
	}
}

func newDiscovery(ctx *context.T, plugins []Plugin) (*idiscovery, error) {
	if len(plugins) == 0 {
		return nil, NewErrNoDiscoveryPlugin(ctx)
	}
	statsMu.Lock()
	statsPrefix := naming.Join("discovery", fmt.Sprint(statsIdx))
	statsIdx++
	statsMu.Unlock()
	d := &idiscovery{
		plugins:       make([]Plugin, len(plugins)),
		tasks:         make(map[*context.T]func()),
		adSessions:    make(map[discovery.AdId]sessionId),
		adSubtasks:    make(map[discovery.AdId]*adSubtask),
		adStopTrigger: NewTrigger(),
		statsPrefix:   statsPrefix,
	}
	copy(d.plugins, plugins)

	// TODO(jhahn): Consider to start a directory server when it is required.
	// For example, scan-only applications would not need it.
	var err error
	if d.dirServer, err = newDirServer(ctx, d); err != nil {
		return nil, err
	}
	return d, nil
}
