// 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 java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.logging.Logger;

import go.Universe;

// 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");

	// also known to bind/seq/ref.go and bind/objc/seq_darwin.m
	private static final int NULL_REFNUM = 41;

	// use single Ref for null Object
	public static final Ref nullRef = new Ref(NULL_REFNUM, null);

	static {
		// Look for the shim class auto-generated by gomobile bind.
		// Its only purpose is to call System.loadLibrary.
		try {
			Class loadJNI = Class.forName("go.LoadJNI");
			setContext(loadJNI.getDeclaredField("ctx").get(null));
		} catch (ClassNotFoundException e) {
			// Ignore, assume the user will load JNI for it.
			log.warning("LoadJNI class not found");
		} catch (NoSuchFieldException e) {
			log.severe("LoadJNI class missing field: " + e);
		} catch (IllegalAccessException e) {
			log.severe("LoadJNI class bad field: " + e);
		}
		init();
		Universe.touch();
	}

	private static native void init();

	// Empty method to run class initializer
	public static void touch() {}

	private Seq() {
	}

	// ctx is an android.context.Context.
	static native void setContext(java.lang.Object ctx);

	public static void incRefnum(int refnum) {
		tracker.incRefnum(refnum);
	}

	// incRef increments the reference count of Java objects.
	// For proxies for Go objects, it calls into the Proxy method
	// incRefnum() to make sure the Go reference count is positive
	// even if the Proxy is garbage collected and its Ref is finalized.
	public static int incRef(Object o) {
		return tracker.inc(o);
	}

	public static int incGoObjectRef(GoObject o) {
		return o.incRefnum();
	}

	// trackGoRef returns a Ref for a Go refnum.
	//
	// 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.
	public static Ref trackGoRef(int refnum) {
		if (refnum > 0) {
			throw new RuntimeException("trackGoRef called with Java refnum " + refnum);
		}
		return new Ref(refnum, null);
	}

	public static Ref getRef(int refnum) {
		return tracker.get(refnum);
	}

	// Increment the Go reference count before sending over a refnum.
	public static native void incGoRef(int refnum);

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

	// decRef is called from seq.FinalizeRef
	static void decRef(int refnum) {
		tracker.dec(refnum);
	}

	// A GoObject is a Java class implemented in Go. When a GoObject
	// is passed to Go, it is wrapped in a Go proxy, to make it behave
	// the same as passing a regular Java class.
	public interface GoObject {
		// Increment refcount and return the refnum of the proxy.
		//
		// The Go reference count need to be bumped while the
		// refnum is passed to Go, to avoid finalizing and
		// invalidating it before being translated on the Go side.
		int incRefnum();
	}
	// A Proxy is a Java object that proxies a Go object. Proxies, unlike
	// GoObjects, are unwrapped to their Go counterpart when deserialized
	// in Go.
	public interface Proxy extends GoObject {}

	// 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,
	// 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
		public final int refnum;

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

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

		Ref(int refnum, Object o) {
			if (refnum < 0) {
				throw new RuntimeException("Ref instantiated with a Go refnum " + refnum);
			}
			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();
		}

		void inc() {
			// Count how many times this ref's Java object is passed to Go.
			if (refcnt == Integer.MAX_VALUE) {
				throw new RuntimeException("refnum " + refnum + " overflow");
			}
			refcnt++;
		}
	}

	static final RefTracker tracker = new RefTracker();

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

		// 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 final RefMap javaObjs = new RefMap();

		// Java objects to refnum
		private final IdentityHashMap<Object, Integer> javaRefs = new IdentityHashMap<>();

		// inc increments the reference count of a Java object when it
		// is sent to Go. inc returns the refnum for the object.
		synchronized int inc(Object o) {
			if (o == null) {
				return NULL_REFNUM;
			}
			if (o instanceof Proxy) {
				return ((Proxy)o).incRefnum();
			}
			Integer refnumObj = javaRefs.get(o);
			if (refnumObj == null) {
				if (next == Integer.MAX_VALUE) {
					throw new RuntimeException("createRef overflow for " + o);
				}
				refnumObj = next++;
				javaRefs.put(o, refnumObj);
			}
			int refnum = refnumObj;
			Ref ref = javaObjs.get(refnum);
			if (ref == null) {
				ref = new Ref(refnum, o);
				javaObjs.put(refnum, ref);
			}
			ref.inc();
			return refnum;
		}

		synchronized void incRefnum(int refnum) {
			Ref ref = javaObjs.get(refnum);
			if (ref == null) {
				throw new RuntimeException("referenced Java object is not found: refnum="+refnum);
			}
			ref.inc();
		}

		// 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 == Seq.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);
				javaRefs.remove(obj.obj);
			}
		}

		// get returns an existing Ref to a Java object.
		synchronized Ref get(int refnum) {
			if (refnum < 0) {
				throw new RuntimeException("ref called with Go refnum " + refnum);
			}
			if (refnum == NULL_REFNUM) {
				return nullRef;
			}
			Ref ref = javaObjs.get(refnum);
			if (ref == null) {
				throw new RuntimeException("unknown java Ref: "+refnum);
			}
			return ref;
		}
	}

	// RefMap is a mapping of integers to Ref objects.
	//
	// The integers can be sparse. In Go this would be a map[int]*Ref.
	static final class RefMap {
		private int next = 0;
		private int live = 0;
		private int[] keys = new int[16];
		private Ref[] objs = new Ref[16];

		RefMap() {}

		Ref get(int key) {
			int i = Arrays.binarySearch(keys, 0, next, key);
			if (i >= 0) {
				return objs[i];
			}
			return null;
		}

		void remove(int key) {
			int i = Arrays.binarySearch(keys, 0, next, key);
			if (i >= 0) {
				if (objs[i] != null) {
					objs[i] = null;
					live--;
				}
			}
		}

		void put(int key, Ref obj) {
			if (obj == null) {
				throw new RuntimeException("put a null ref (with key "+key+")");
			}
			int i = Arrays.binarySearch(keys, 0, next, key);
			if (i >= 0) {
				if (objs[i] == null) {
					objs[i] = obj;
					live++;
				}
				if (objs[i] != obj) {
					throw new RuntimeException("replacing an existing ref (with key "+key+")");
				}
				return;
			}
			if (next >= keys.length) {
				grow();
				i = Arrays.binarySearch(keys, 0, next, key);
			}
			i = ~i;
			if (i < next) {
				// Insert, shift everything afterwards down.
				System.arraycopy(keys, i, keys, i+1, next-i);
				System.arraycopy(objs, i, objs, i+1, next-i);
			}
			keys[i] = key;
			objs[i] = obj;
			live++;
			next++;
		}

		private void grow() {
			// Compact and (if necessary) grow backing store.
			int[] newKeys;
			Ref[] newObjs;
			int len = 2*roundPow2(live);
			if (len > keys.length) {
				newKeys = new int[keys.length*2];
				newObjs = new Ref[objs.length*2];
			} else {
				newKeys = keys;
				newObjs = objs;
			}

			int j = 0;
			for (int i = 0; i < keys.length; i++) {
				if (objs[i] != null) {
					newKeys[j] = keys[i];
					newObjs[j] = objs[i];
					j++;
				}
			}
			for (int i = j; i < newKeys.length; i++) {
				newKeys[i] = 0;
				newObjs[i] = null;
			}

			keys = newKeys;
			objs = newObjs;
			next = j;

			if (live != next) {
				throw new RuntimeException("bad state: live="+live+", next="+next);
			}
		}

		private static int roundPow2(int x) {
			int p = 1;
			while (p < x) {
				p *= 2;
			}
			return p;
		}
	}
}
