// Copyright 2014 The Go 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 go;

import android.app.Application;
import android.content.Context;
import android.util.SparseArray;
import android.util.SparseIntArray;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;

// Seq is a sequence of machine-dependent encoded values.
// Used by automatically generated language bindings to talk to Go.
public class Seq {
	private static Logger log = Logger.getLogger("GoSeq");

	static {
		// Look for the shim class auto-generated by gomobile bind.
		// Its only purpose is to call System.loadLibrary.
		try {
			Class.forName("go.LoadJNI");
		} catch (ClassNotFoundException e) {
			// Ignore, assume the user will load JNI for it.
                        log.warning("LoadJNI class not found");
		}

		try {
			// TODO(hyangah): check proguard rule.
			Application appl = (Application)Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null);
			Context ctx = appl.getApplicationContext();
			setContext(ctx);

		} catch (Exception e) {
                        log.warning("Global context not found: " + e);
		}

		initSeq();
		new Thread("GoSeq") {
			public void run() { Seq.receive(); }
		}.start();
	}

	@SuppressWarnings("UnusedDeclaration")
	private long memptr; // holds C-allocated pointer

	public Seq() {
		ensure(64);
	}

	static native void setContext(Context ctx);

	// Ensure that at least size bytes can be written to the Seq.
	// Any existing data in the buffer is preserved.
	public native void ensure(int size);

	// Moves the internal buffer offset back to zero.
	// Length and contents are maintained. Data can be read after a reset.
	public native void resetOffset();

	public native void log(String label);

	public native boolean readBool();
	public native byte readInt8();
	public native short readInt16();
	public native int readInt32();
	public native long readInt64();
	public long readInt() { return readInt64(); }

	public native float readFloat32();
	public native double readFloat64();
	public native String readUTF16();
	public String readString() { return readUTF16(); }
	public native byte[] readByteArray();

	public native void writeBool(boolean v);
	public native void writeInt8(byte v);
	public native void writeInt16(short v);
	public native void writeInt32(int v);
	public native void writeInt64(long v);
	public void writeInt(long v) { writeInt64(v); }

	public native void writeFloat32(float v);
	public native void writeFloat64(double v);
	public native void writeUTF16(String v);
	public void writeString(String v) { writeUTF16(v); }
	public native void writeByteArray(byte[] v);

	public void writeRef(Ref ref) {
		tracker.inc(ref);
		writeInt32(ref.refnum);
	}

	public Ref readRef() {
		int refnum = readInt32();
		return tracker.get(refnum);
	}

	static native void initSeq();

	// Informs the Go ref tracker that Java is done with this ref.
	static native void destroyRef(int refnum);

	// createRef creates a Ref to a Java object.
	public static Ref createRef(Seq.Object o) {
		return tracker.createRef(o);
	}

	// sends a function invocation request to Go.
	//
	// Blocks until the function completes.
	// If the request is for a method, the first element in src is
	// a Ref to the receiver.
	public static native void send(String descriptor, int code, Seq src, Seq dst);

	// recv returns the next request from Go for a Java call.
	static native void recv(Seq in, Receive params);

	// recvRes sends the result of a Java call back to Go.
	static native void recvRes(int handle, Seq out);

	static final class Receive {
		int refnum;
		int code;
		int handle;
	}

	protected void finalize() throws Throwable {
		super.finalize();
		free();
	}
	private native void free();

	private static final ExecutorService receivePool = Executors.newCachedThreadPool();

	// receive listens for callback requests from Go, invokes them on a thread
	// pool and sends the responses.
	public static void receive() {
		Seq.Receive params = new Seq.Receive();
		while (true) {
			final Seq in = new Seq();
			Seq.recv(in, params);

			final int code = params.code;
			final int handle = params.handle;
			final int refnum = params.refnum;

			if (code == -1) {
				// Special signal from seq.FinalizeRef.
				tracker.dec(refnum);
				Seq out = new Seq();
				Seq.recvRes(handle, out);
				continue;
			}

			receivePool.execute(new Runnable() {
				public void run() {
					Ref r = tracker.get(refnum);
					Seq out = new Seq();
					r.obj.call(code, in, out);
					Seq.recvRes(handle, out);
				}
			});
		}
	}

	// An Object is a Java object that matches a Go object.
	// The implementation of the object may be in either Java or Go,
	// with a proxy instance in the other language passing calls
	// through to the other language.
	//
	// Don't implement an Object directly. Instead, look for the
	// generated abstract Stub.
	public interface Object {
		public Ref ref();
		public void call(int code, Seq in, Seq out);
	}

	// A Ref is an object tagged with an integer for passing back and
	// forth across the language boundary.
	//
	// A Ref may represent either an instance of a Java Object subclass,
	// or an instance of a Go object. The explicit allocation of a Ref
	// is used to pin Go object instances when they are passed to Java.
	// The Go Seq library maintains a reference to the instance in a map
	// keyed by the Ref number. When the JVM calls finalize, we ask Go
	// to clear the entry in the map.
	public static final class Ref {
		// refnum < 0: Go object tracked by Java
		// refnum > 0: Java object tracked by Go
		int refnum;

		int refcnt;  // for Java obj: track how many times sent to Go.

		public Seq.Object obj;  // for Java obj: pointers to the Java obj.

		private Ref(int refnum, Seq.Object o) {
			this.refnum = refnum;
			this.refcnt = 0;
			this.obj = o;
		}

		@Override
		protected void finalize() throws Throwable {
			if (refnum < 0) {
				// Go object: signal Go to decrement the reference count.
				Seq.destroyRef(refnum);
			}
			super.finalize();
		}
	}

	static final RefTracker tracker = new RefTracker();

	static final class RefTracker {
		private static final int REF_OFFSET = 42;

		// use single Ref for null Seq.Object
		private static final Ref nullRef = new Ref(REF_OFFSET - 1, null);

		// Next Java object reference number.
		//
		// Reference numbers are positive for Java objects,
		// and start, arbitrarily at a different offset to Go
		// to make debugging by reading Seq hex a little easier.
		private int next = REF_OFFSET; // next Java object ref

		// Java objects that have been passed to Go. refnum -> Ref
		// The Ref obj field is non-null.
		// This map pins Java objects so they don't get GCed while the
		// only reference to them is held by Go code.
		private SparseArray<Ref> javaObjs = new SparseArray<Ref>();

		// inc increments the reference count of a Java object when it
		// is sent to Go.
		synchronized void inc(Ref ref) {
			int refnum = ref.refnum;
			if (refnum <= 0) {
				// We don't keep track of the Go object.
				return;
			}
			if (refnum == nullRef.refnum) {
				return;
			}
			// Count how many times this ref's Java object is passed to Go.
			if (ref.refcnt == Integer.MAX_VALUE) {
				throw new RuntimeException("refnum " + refnum + " overflow");
			}
			ref.refcnt++;
			Ref obj = javaObjs.get(refnum);
			if (obj == null) {
				javaObjs.put(refnum, ref);
			}
		}

		// dec decrements the reference count of a Java object when
		// Go signals a corresponding proxy object is finalized.
		// If the count reaches zero, the Java object is removed
		// from the javaObjs map.
		synchronized void dec(int refnum) {
			if (refnum <= 0) {
				// We don't keep track of the Go object.
				// This must not happen.
				log.severe("dec request for Go object "+ refnum);
				return;
			}
			if (refnum == nullRef.refnum) {
				return;
			}
			// Java objects are removed on request of Go.
			Ref obj = javaObjs.get(refnum);
			if (obj == null) {
				throw new RuntimeException("referenced Java object is not found: refnum="+refnum);
			}
			obj.refcnt--;
			if (obj.refcnt <= 0) {
				javaObjs.remove(refnum);
			}
		}

		synchronized Ref createRef(Seq.Object o) {
			if (o == null) {
				return nullRef;
			}
			if (next == Integer.MAX_VALUE) {
				throw new RuntimeException("createRef overflow for " + o);
			}
			int refnum = next++;
			Ref ref = new Ref(refnum, o);
			javaObjs.put(refnum, ref);
			return ref;
		}

		// get returns an existing Ref to either a Java or Go object.
		// It may be the first time we have seen the Go object.
		//
		// TODO(crawshaw): We could cut down allocations for frequently
		// sent Go objects by maintaining a map to weak references. This
		// however, would require allocating two objects per reference
		// instead of one. It also introduces weak references, the bane
		// of any Java debugging session.
		//
		// When we have real code, examine the tradeoffs.
		synchronized Ref get(int refnum) {
			if (refnum > 0) {
				if (refnum == nullRef.refnum) {
					return nullRef;
				}
				Ref ref = javaObjs.get(refnum);
				if (ref == null) {
					throw new RuntimeException("unknown java Ref: "+refnum);
				}
				return ref;
			} else {
				// Go object.
				return new Ref(refnum, null);
			}
		}
	}
}
