// 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()

	chRef := jutil.GoNewRef(&ch) // Un-refed when jNativeScanHandler is finalized.
	jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(chRef))
	if err != nil {
		jutil.GoDecRef(chRef)
		done()
		return err
	}
	err = jutil.CallVoidMethod(env, p.jPlugin, "startScan", []jutil.Sign{jutil.StringSign, scanHandlerSign}, interfaceName, jNativeScanHandler)
	if err != nil {
		done()
		return err
	}

	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 (p *plugin) Close() {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()

	jutil.CallVoidMethod(env, p.jPlugin, "close", 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
}
