/*
 * Copyright (C) 2018-2020 Western Digital Corporation or its affiliates
 * Copyright (C) 2017-2018 Wearable, Inc.
 * Copyright (C) 2000-2012 leJOS Contributors
 * Copyright (C) 2000 Jose H. Solorzano and TinyVM Contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is “Incompatible With Secondary Licenses”,
 * as defined by the Mozilla Public License, v. 2.0.
 */

package java.lang;

import java.io.PrintStream;

import org.naniteproject.NaniteOutputStream;

/**
 * System utilities.
 */
public final class System
{
	private System() {}

	/**
	 * Copies one array to another.
	 */
	public static native void arraycopy (Object src, int srcOffset, Object dest, int destOffset, int length);

	/**
	 * Current time expressed in milliseconds. 
	 */
	public static native long currentTimeMillis();

	private native static int getDataAddress (Object obj);

	/**
	 * Collect garbage
	 */
	public static native void gc();
	
	/**
	  * Return the time since system start in nano-seconds
	  * @return
	  */
	 public static native long nanoTime();


	/**
	 * Terminate the application.
	 */
	public static void exit(int code)
	{
		Runtime.getRuntime().exit(code);
	}

	/**
	 * Get the singleton instance of Runtime.
	 */
	public static Runtime getRuntime() {
		return Runtime.getRuntime();
	}

	public static int identityHashCode(Object obj) {
		return System.getDataAddress(obj);
	}

	public static PrintStream out = new PrintStream(new NaniteOutputStream());

	/**
	 * Redirect System.out
	 * 
	 * @param out a PrintStream
	 */
	public static void setOut(PrintStream out) {
		System.out = out;
	}

	public static PrintStream err = new PrintStream(new NaniteOutputStream());

	/**
	 * Redirect System.err
	 * 
	 * @param err a PrintStream
	 */
	public static void setErr(PrintStream err) {
		System.err = err;
	}

	public static String getProperty(String str, String def) {
		String result = getProperty(str);
		if(result.equals("")) {
			return def;
		} else {
			return result;
		}
	}

	public static String getProperty(String str) {
		if(str.equals("line.separator")) {
			return "\n";
		} else if(str.equals("file.encoding")) {
			return "UTF-8";
		} else if(str.equals("os.name")) {
			// TODO: Is this what we want?
			return "Nanite";
		} else if(str.equals("sun.nio.cs.map")) {
			return "";
		} else if(str.equals("os.arch")) {
			// TODO: Is this what we want?
			return "ARM";
		} else if(str.equals("jdk.map.althashing.threshold")) {
			return "-1";
		} else if(str.equals("java.util.Arrays.useLegacyMergeSort")) {
			return "false";
		} else if(str.equals("user.language")) {
			return "en";
		} else if(str.equals("jdk.util.TimeZone.allowSetDefault")) {
			return "false";
		} else if(str.equals("user.timezone")) {
			return "GMT";
		} else if(str.equals("user.country")) {
			return "USA";
		}
		return "";
	}

	public static String lineSeparator() { return getProperty("file.encoding"); }

}



