// Copyright 2015 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 main

import (
	"sync"

	"mojo/public/go/application"
	"mojo/public/go/bindings"
	"mojo/public/go/system"
	mojom "mojom/vanadium/discovery"

	"v.io/v23"
	"v.io/v23/context"

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

	"vanadium/discovery/internal"
)

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

type discoveryDelegate struct {
	// mu protects stubs.  All calls to methods on the delegate by
	// mojo will be done in the same goroutine.  We need mu so
	// we can clean up stubs that fail because of pipe errors because
	// each stub serves all its requests in its own goroutine.
	mu    sync.Mutex
	stubs map[*bindings.Stub]struct{}

	ctx      *context.T
	shutdown v23.Shutdown
	impl     *internal.DiscoveryService
}

func (d *discoveryDelegate) Initialize(c application.Context) {
	// TODO(bjornick): Calling 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.
	d.ctx, d.shutdown = v23.Init()
	d.impl = internal.NewDiscoveryService(d.ctx)
}

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

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.StopAll()
	d.shutdown()
	d.mu.Lock()
	for stub := range d.stubs {
		stub.Close()
	}
	d.mu.Unlock()
}

//export MojoMain
func MojoMain(handle C.MojoHandle) C.MojoResult {
	application.Run(&discoveryDelegate{stubs: map[*bindings.Stub]struct{}{}}, system.MojoHandle(handle))
	return C.MOJO_RESULT_OK
}

func main() {
}
