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

	"v.io/v23/context"
	"v.io/v23/discovery"
	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
}

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, ch chan<- *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)
		for {
			select {
			case adinfo := <-listener:
				if adinfo.Lost {
					delete(seen, adinfo.Ad.Id)
				} else {
					prev := seen[adinfo.Ad.Id]
					if prev != nil && (prev.Hash == adinfo.Hash || prev.TimestampNs >= adinfo.TimestampNs) {
						continue
					}
					seen[adinfo.Ad.Id] = adinfo
				}
				copied := *adinfo
				select {
				case ch <- &copied:
				case <-ctx.Done():
					return
				}
			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()
	statName := fmt.Sprintf("discovery/ble/driver/%d", statIdx)
	statIdx++
	stats.NewStringFunc(statName, func() string {
		return driver.DebugString()
	})
	statMu.Unlock()
	p := &plugin{
		advertiser: newAdvertiser(ctx, driver),
		scanner:    newScanner(ctx, driver, ttl),
		adStopper:  idiscovery.NewTrigger(),
	}
	runtime.SetFinalizer(p, func(p *plugin) { stats.Delete(statName) })
	return p, nil
}
