// 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.

// +build android

package plugins

import (
	"runtime"

	"v.io/v23/context"

	idiscovery "v.io/x/ref/lib/discovery"
	dfactory "v.io/x/ref/lib/discovery/factory"

	jutil "v.io/x/jni/util"
	jcontext "v.io/x/jni/v23/context"
)

// #include "jni.h"
import "C"

type plugin struct {
	jPlugin jutil.Object
	trigger *idiscovery.Trigger
}

func (p *plugin) Advertise(ctx *context.T, adinfo *idiscovery.AdInfo, done func()) error {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()

	jAdInfo, err := jutil.JVomCopy(env, adinfo, jAdInfoClass)
	if err != nil {
		done()
		return err
	}
	err = jutil.CallVoidMethod(env, p.jPlugin, "startAdvertising", []jutil.Sign{adInfoSign}, jAdInfo)
	if err != nil {
		done()
		return err
	}

	jAdInfo = jutil.NewGlobalRef(env, jAdInfo)
	stop := func() {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		jutil.CallVoidMethod(env, p.jPlugin, "stopAdvertising", []jutil.Sign{adInfoSign}, jAdInfo)
		jutil.DeleteGlobalRef(env, jAdInfo)
		done()
	}
	p.trigger.Add(stop, ctx.Done())
	return nil
}

func (p *plugin) Scan(ctx *context.T, interfaceName string, ch chan<- *idiscovery.AdInfo, done func()) error {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()

	jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(&ch)))
	if err != nil {
		done()
		return err
	}
	err = jutil.CallVoidMethod(env, p.jPlugin, "startScan", []jutil.Sign{jutil.StringSign, scanHandlerSign}, interfaceName, jNativeScanHandler)
	if err != nil {
		done()
		return err
	}

	jutil.GoRef(&ch) // Will be unrefed when jNativeScanHandler is finalized.
	jNativeScanHandler = jutil.NewGlobalRef(env, jNativeScanHandler)
	stop := func() {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		jutil.CallVoidMethod(env, p.jPlugin, "stopScan", []jutil.Sign{scanHandlerSign}, jNativeScanHandler)
		jutil.DeleteGlobalRef(env, jNativeScanHandler)
		done()
	}
	p.trigger.Add(stop, ctx.Done())
	return nil
}

func newPluginFactory(env jutil.Env, jPluginClass jutil.Class) func(*context.T, string) (idiscovery.Plugin, error) {
	return func(ctx *context.T, host string) (idiscovery.Plugin, error) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()

		// We pass the global context of the android vanadium runtime, since the context of the discovery
		// factory does not have an Android context.
		jCtx, err := jcontext.JavaContext(env, ctx, nil)
		if err != nil {
			return nil, err
		}
		jPlugin, err := jutil.NewObject(env, jPluginClass, []jutil.Sign{contextSign, jutil.StringSign}, jCtx, host)
		if err != nil {
			return nil, err
		}
		// Reference Plugin; it will be de-referenced when the plugin is garbage-collected.
		jPlugin = jutil.NewGlobalRef(env, jPlugin)
		p := &plugin{
			jPlugin: jPlugin,
			trigger: idiscovery.NewTrigger(),
		}
		runtime.SetFinalizer(p, func(*plugin) {
			env, freeFunc := jutil.GetEnv()
			jutil.DeleteGlobalRef(env, p.jPlugin)
			freeFunc()
		})
		return p, nil
	}
}

func initPluginFactories(env jutil.Env) error {
	jPluginClass, err := jutil.JFindClass(env, "io/v/android/impl/google/discovery/plugins/ble/BlePlugin")
	if err != nil {
		return err
	}
	dfactory.SetPluginFactory("ble", newPluginFactory(env, jPluginClass))
	return nil
}
