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

	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) {
			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 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 == NULL_REFNUM) {
				return nullRef;
			} else if (refnum > 0) {
				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);
			}
		}
	}

	// 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;
		}
	}
}
