package internal

import (
	"sync"

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

	"mojo/public/go/bindings"
	mojom "mojom/vanadium/discovery"
)

// DiscoveryService implements the mojom interface mojom/vanadium/discovery.DiscoveryService.  It
// is basically a thin wrapper around the Vanadium Discovery API.
type DiscoveryService struct {
	ctx     *context.T
	s       discovery.T

	// mu protects pending* and next*
	mu sync.Mutex

	// The id to assign the next advertisement.
	nextAdv int32
	// A map of advertisement ids to the cancellation function.
	activeAdvs map[int32]func()
	// The id to assign to the next scan.
	nextScan int32
	// A map of scan id to the cancellataion func()
	activeScans map[int32]func()
}

func v2mError(err error) *mojom.Error {
	return &mojom.Error{
		Id:  string(verror.ErrorID(err)),
		Action: int32(verror.Action(err)),
		Msg: err.Error(),
	}
}

// NewDiscoveryService returns a new DiscoveryService bound to the context and the Vanadium
// Discovery implementation passed in.
func NewDiscoveryService(ctx *context.T, vDiscovery discovery.T) *DiscoveryService {
	return &DiscoveryService{
		ctx:          ctx,
		s:            vDiscovery,
		activeAdvs:  map[int32]func(){},
		activeScans: map[int32]func(){},
	}
}

// Advertise advertises the mojom service passed only to the giveen blessing patterns. Returns the
// handle to this Advertise call.
func (d *DiscoveryService) Advertise(s mojom.Service, patterns []string) (int32, *mojom.Error, error) {
	vService := discovery.Service{
		InstanceUuid:  s.InstanceUuid,
		InterfaceName: s.InterfaceName,
		Attrs:         discovery.Attributes(s.Attrs),
		Addrs:         s.Addrs,
	}

	ctx, cancel := context.WithCancel(d.ctx)

	err := d.s.Advertise(ctx, vService, nil)
	if err != nil {
		cancel()
		return 0, v2mError(err), nil
	}
	d.mu.Lock()
	id := d.nextAdv
	d.activeAdvs[id] = cancel
	d.nextAdv++
	d.mu.Unlock()
	return id, nil, nil
}

// StopAdvertising stops advertising for the given advertising id.
func (d *DiscoveryService) StopAdvertising(handle int32) error {
	d.mu.Lock()
	cancel := d.activeAdvs[handle]
	delete(d.activeAdvs, handle)
	d.mu.Unlock()
	if cancel != nil {
		cancel()
	}
	return nil
}

func v2mService(s discovery.Service) mojom.Service {
	return mojom.Service{
		InstanceUuid:  s.InstanceUuid,
		InterfaceName: s.InterfaceName,
		Attrs:         s.Attrs,
		Addrs:         s.Addrs,
	}
}

// Scan scans for all services that match the query string passed in and calls scanHandler with updates.
// Returns the handle to this Scan.
func (d *DiscoveryService) Scan(query string, scanHandler mojom.ScanHandler_Pointer) (int32, *mojom.Error, error) {
	ctx, cancel := context.WithCancel(d.ctx)
	proxy := mojom.NewScanHandlerProxy(scanHandler, bindings.GetAsyncWaiter())
	scanCh, err := d.s.Scan(ctx, query)
	if err != nil {
		cancel()
		return 0, v2mError(err), nil
	}
	d.mu.Lock()
	id := d.nextScan
	d.activeScans[id] = cancel
	d.nextScan++
	d.mu.Unlock()

	go func() {
		for v := range scanCh {
			switch value := v.(type) {
			case discovery.UpdateFound:
				proxy.Found(v2mService(value.Value.Service))
			case discovery.UpdateLost:
				proxy.Lost(v2mService(value.Value.Service))
			}
		}
	}()
	return id, nil, nil
}

// SopScan Stops the scan.
func (d *DiscoveryService) StopScan(handle int32) error {
	d.mu.Lock()
	cancel := d.activeScans[handle]
	delete(d.activeScans, handle)
	d.mu.Unlock()
	if cancel != nil {
		cancel()
	}
	return nil
}

// Stop Stops all scans and advertisements.
func (d *DiscoveryService) Stop() {
	d.mu.Lock()
	for _, cancel := range d.activeScans {
		cancel()
	}

	for _, cancel := range d.activeAdvs {
		cancel()
	}
	d.mu.Unlock()
}
