package main

import (
	"v.io/v23"
	idiscovery "v.io/x/ref/lib/discovery"
	"v.io/x/ref/lib/discovery/plugins/ble"
	"v.io/x/ref/lib/discovery/plugins/mdns"

	_ "v.io/x/ref/runtime/factories/generic"

	mojom "mojom/vanadium/discovery"
	"vanadium/discovery/internal"

	"mojo/public/go/application"
	"mojo/public/go/bindings"
	"mojo/public/go/system"
	"v.io/v23/context"
)

//#include "mojo/public/c/system/types.h"
import "C"

type discoveryDelegate struct {
	ctx      *context.T
	stubs    []*bindings.Stub
	impl     *internal.DiscoveryService
	shutdown v23.Shutdown
}

func (d *discoveryDelegate) Initialize(c application.Context) {
	// TODO(bjornick): Caling init multiple times in the same process
	// will be bad.  For now, this is ok because this is the only
	// vanadium service that will be used in the demos and each go library
	// will be in its own process.
	ctx, shutdown := v23.Init()
	host := c.Args()[1]
	ctx.Info("Starting discovery with name", host)
	mplugin, err := mdns.New(host)
	pluginList := []idiscovery.Plugin{}
	if err != nil {
		ctx.Error("Failed to start MDNS plugin", err)
	} else {
		pluginList = append(pluginList, mplugin)
	}

	bplugin, err := ble.NewPlugin(host)
	if err != nil {
		ctx.Error("Failed to start BLE plugin", err)
	} else {
		pluginList = append(pluginList, bplugin)
	}

	if len(pluginList) == 0 {
		c.Close()
		return
	}
	d.impl = internal.NewDiscoveryService(ctx, idiscovery.New(pluginList))
	d.shutdown = shutdown
}

func (d *discoveryDelegate) addAndServeStub(stub *bindings.Stub) {
	d.stubs = append(d.stubs, stub)
	go func() {
		for {
			if err := stub.ServeRequest(); err != nil {
				connectionErr, ok := err.(*bindings.ConnectionError)
				if !ok || !connectionErr.Closed() {
					d.ctx.Error(err)
				}
				break
			}
		}
	}()
}

type advertiseFactory struct {
	d *discoveryDelegate
}

func (a *advertiseFactory) Create(request mojom.Advertiser_Request) {
	stub := mojom.NewAdvertiserStub(request, a.d.impl, bindings.GetAsyncWaiter())
	a.d.addAndServeStub(stub)
}

type scannerFactory struct {
	d *discoveryDelegate
}

func (s *scannerFactory) Create(request mojom.Scanner_Request) {
	stub := mojom.NewScannerStub(request, s.d.impl, bindings.GetAsyncWaiter())
	s.d.addAndServeStub(stub)
}

func (d *discoveryDelegate) AcceptConnection(connection *application.Connection) {
	advFactory := &advertiseFactory{d: d}
	scanFactory := &scannerFactory{d: d}
	connection.ProvideServices(&mojom.Advertiser_ServiceFactory{advFactory}, &mojom.Scanner_ServiceFactory{scanFactory})
}

func (d *discoveryDelegate) Quit() {
	d.impl.Stop()
	d.shutdown()
	for _, stub := range d.stubs {
		stub.Close()
	}
}

//export MojoMain
func MojoMain(handle C.MojoHandle) C.MojoResult {
	application.Run(&discoveryDelegate{}, system.MojoHandle(handle))
	return C.MOJO_RESULT_OK
}

func main() {
}
