package discovery

import (
	mojom "mojom/vanadium/discovery"
	"v.io/v23/discovery"
	"sync"
	"v.io/v23/context"
	"v.io/v23/security/access"
	"v.io/v23/verror"
	"mojo/public/go/bindings"
)

type discoveryService struct {
	mu sync.Mutex
	ctx *context.T
	s discovery.T
	nextAdv int32
	pendingAdvs map[int32]chan struct{}
	nextScan int32;
	pendingScans map[int32]chan struct{}

}


func converToErrorStruct(err error) *mojom.Error {
	outErr := &mojom.Error{
			Id: "v.io/verror/Unknown",
			Msg: err.Error(),
		}
		if e, ok := err.(verror.E); ok {
			outErr.Id = string(e.ID)
			outErr.Action = int32(e.Action)
		}
	return outErr
}

func (d *discoveryService) Advertisement(s mojom.Service, patterns []string) (int32, *mojom.Error) {
	vService := discovery.Service{
		InstanceUuid: s.InstanceUuid,
		InterfaceName: s.InterfaceName,
		Attrs: discovery.Attributes(s.Attrs),
		Addrs: s.Addrs,
	}

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

	err := d.s.Advertise(ctx, vService, access.Permissions{})
	if err != nil {
		return 0, converToErrorStruct(err)
	}
	ch := make(chan struct{})
	d.mu.Lock()
	id := d.nextAdv
	d.pendingAdvs[id] = ch
	d.nextAdv++
	d.mu.Unlock()
	go func() {
		<-ch
		c()
	}()
	return id, nil
}

func (d *discoveryService) StopAdvertising(handle int32) {
	d.mu.Lock()
	ch := d.pendingAdvs[handle]
	d.mu.Unlock()
	if ch != nil {
		close(ch)
	}
}

func (d *discoveryService) Scan(query string, scanHandler mojom.ScanHandler_Pointer) (int32, *mojom.Error)  {
	ctx, c := context.WithCancel(d.ctx)
	proxy := mojom.NewScanHandlerProxy(scanHandler, bindings.GetAsyncWaiter())
	scanCh, err := d.s.Scan(ctx, query)
	go func() {
		for v := range scanCh {
			switch v.Interface().(type) {
			case discovery.UpdateFound
			}
			if v.Index() == 0 {
				v.
				proxy.Found()
			}
		}
	}()
}
