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

// +build android

package discovery
import (
	"bytes"
	"unsafe"

	"v.io/v23/context"

	"v.io/x/ref/lib/discovery"
	"v.io/x/ref/runtime/factories/android"

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

	"third_party/go/tool/android_arm/src/runtime"
)

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

var (
	androidContextSign = jutil.ClassSign("android.content.Context")
	contextSign = jutil.ClassSign("io.v.v23.Context")
	advertisementSign = jutil.ClassSign("io.v.x.ref.lib.discovery.Advertisement")
	uuidSign = jutil.ClassSign("java.util.UUID")
	scanHandlerSign = jutil.ClassSign("io.v.impl.google.lib.discovery.ScanHandler")
)


func NewPluginCreator(env jutil.Env, context C.jobject) func(string) (discovery.Plugin, error) {
	// Reference Java VPrincipal; it will be de-referenced when the Go Principal
	// created below is garbage-collected (through the finalizer callback we
	// setup just below).
	jContext = jutil.NewGlobalRef(env, context)
	return func(host string) (discovery.Plugin, error) {
		env, freeFunc := jutil.GetEnv()
		defer freeFunc()
		jPlugin, err := jutil.NewObject(env, jBlePluginClass, []jutil.Sign{androidContextSign}, context)

		jutil.DeleteGlobalRef(env, jContext)
		if err != nil {
			return nil, err
		}
		jplugin = jutil.NewGlobalRef(env, jPlugin)
		p := &plugin{
			trigger: discovery.NewTrigger(),
			jPlugin: jPlugin,
		}
		runtime.SetFinalizer(p, func(p *plugin) {
			env, freeFunc := jutil.GetEnv()
			defer freeFunc()
			jutil.DeleteGlobalRef(env, p.jPlugin)
		})
		return p, nil
	}

}

type plugin struct {
	trigger *discovery.Trigger
	jPlugin C.jobject
}

// Plugin is the basic interface for a plugin to discovery service.
// All implementation should be goroutine-safe.
type Plugin interface {
	// Advertise advertises the advertisement. Advertising will continue until
	// the context is canceled or exceeds its deadline. done should be called
	// once when advertising is done or canceled.
	Advertise(ctx *context.T, ad Advertisement, done func()) error

	// Scan scans services that match the service uuid and returns scanned
	// advertisements to the channel. A zero-value service uuid means any service.
	// Scanning will continue until the context is canceled or exceeds its
	// deadline. done should be called once when scanning is done or canceled.
	//
	// TODO(jhahn): Pass a filter on service attributes.
	Scan(ctx *context.T, serviceUuid Uuid, ch chan<- Advertisement, done func()) error
}
func (p *plugin) Advertise(ctx *context.T, ad discovery.Advertisement, done func()) error {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jContext, err := jcontext.NewJavaContext(env, ctx)
	if err != nil {
		return err
	}
	jAdv, err := jutil.JVomCopy(env, ad, jAdvertisementClass)
	if err != nil {
		return err
	}

	err := jutil.CallVoidMethod(env, p.jPlugin, "addAdvertisesment", []jutil.Sign{contextSign, advertisementSign}, jContext, jAdv)

	p.trigger.Add(done, ctx.Done())

	return err
}

func (p *plugin) Scan(ctx *context.T, serviceUuid discovery.Uuid, ch chan<- discovery.Advertisement, done func()) error {
	env, freeFunc := jutil.GetEnv()
	defer freeFunc()
	jContext, err := jcontext.NewJavaContext(env, ctx)
	if err != nil {
		return err
	}

	jUuid, err := convertToJavaUUID(env, serviceUuid)

	if err != nil {
		return err
	}


	chPtr := &ch
	jutil.GoRef(chPtr)
	jNativeScanHandler, err := jutil.NewObject(env, jNativeScanHandlerClass, []jutil.Sign{jutil.LongSign}, int64(jutil.PtrValue(chPtr)))
	if err != nil {
		return err
	}

	err = jutil.CallVoidMethod(env, p.jPlugin, "addScanner", []jutil.Sign{contextSign, uuidSign, scanHandlerSign},
		jContext, jUuid, jNativeScanHandler)

	if err != nil {
		return err
	}
	p.trigger.Add(done, ctx.Done())
	return nil
}


func convertToJavaUUID(env, jutil.Env, uuid discovery.Uuid) (C.jobject, error) {
	buf := bytes.NewBuffer(uuid)
	var high, low int64
	binary.Read(buf, binary.BigEndian, &high)
	binary.Read(buf, binary.BigEndian, &low)
	jUUID, err := jutil.NewObject(env, jUUIDClass, []jutil.Sign{jutil.LongSign, jutil.LongSign}, high, low)
}
