// Copyright 2016 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 ble

import (
	"bytes"
	"fmt"
	"runtime"
	"sync"
	"time"

	"v.io/v23/context"
	"v.io/v23/discovery"
	"v.io/v23/naming"
	idiscovery "v.io/x/ref/lib/discovery"
	"v.io/x/ref/lib/stats"
)

const (
	// TTL for scanned advertisement. If we do not see the advertisement again
	// during that period, we send a "Lost" notification.
	defaultTTL = 90 * time.Second
)

var (
	statMu  sync.Mutex
	statIdx int
)

type plugin struct {
	advertiser *advertiser
	scanner    *scanner
	adStopper  *idiscovery.Trigger
	statPrefix string
}

func (p *plugin) Advertise(ctx *context.T, adinfo *idiscovery.AdInfo, done func()) (err error) {
	if err := p.advertiser.addAd(adinfo); err != nil {
		done()
		return err
	}
	stop := func() {
		p.advertiser.removeAd(adinfo)
		done()
	}
	p.adStopper.Add(stop, ctx.Done())
	return nil
}

func (p *plugin) Scan(ctx *context.T, interfaceName string, callback func(*idiscovery.AdInfo), done func()) error {
	go func() {
		defer done()

		listener := p.scanner.addListener(interfaceName)
		defer p.scanner.removeListener(interfaceName, listener)

		seen := make(map[discovery.AdId]*idiscovery.AdInfo)

		// TODO(ashankar,jhahn): To prevent plugins from stepping over
		// each other (e.g., a Lost even from one undoing a Found event
		// from another), the discovery implementation that uses
		// plugins should be made aware of the plugin that sent the event.
		// In that case, perhaps these stats should also be exported there,
		// rather than in each plugin implementation?
		stat := naming.Join(p.statPrefix, "seen")
		var seenMu sync.Mutex // Safety between this goroutine and stats
		stats.NewStringFunc(stat, func() string {
			seenMu.Lock()
			defer seenMu.Unlock()
			buf := new(bytes.Buffer)
			for k, v := range seen {
				fmt.Fprintf(buf, "%s: %v\n\n", k, *v)
			}
			return buf.String()
		})
		defer stats.Delete(stat)
		for {
			select {
			case adinfo := <-listener:
				if adinfo.Lost {
					seenMu.Lock()
					delete(seen, adinfo.Ad.Id)
					seenMu.Unlock()
				} else if prev := seen[adinfo.Ad.Id]; prev != nil && (prev.Hash == adinfo.Hash || prev.TimestampNs >= adinfo.TimestampNs) {
					continue
				} else {
					seenMu.Lock()
					seen[adinfo.Ad.Id] = adinfo
					seenMu.Unlock()
				}
				copied := *adinfo
				callback(&copied)
			case <-ctx.Done():
				return
			}
		}
	}()
	return nil
}

func (p *plugin) Close() {
	p.scanner.shutdown()
}

// New returns a new BLE plugin instance with default ttl (90s).
//
// TODO(jhahn): Rename to New() once we remove old codes.
func New(ctx *context.T, host string) (idiscovery.Plugin, error) {
	return newWithTTL(ctx, host, defaultTTL)
}

func newWithTTL(ctx *context.T, host string, ttl time.Duration) (idiscovery.Plugin, error) {
	driver, err := driverFactory(ctx, host)
	if err != nil {
		return nil, err
	}
	statMu.Lock()
	statPrefix := naming.Join("discovery", "ble", fmt.Sprint(statIdx))
	statIdx++
	stats.NewStringFunc(naming.Join(statPrefix, "driver"), func() string {
		return driver.DebugString()
	})
	statMu.Unlock()
	p := &plugin{
		advertiser: newAdvertiser(ctx, driver),
		scanner:    newScanner(ctx, driver, ttl),
		adStopper:  idiscovery.NewTrigger(),
		statPrefix: statPrefix,
	}
	runtime.SetFinalizer(p, func(p *plugin) { stats.Delete(statPrefix) })
	return p, nil
}
