/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.runtime.internal.adaptor;

import java.util.*;
import org.eclipse.osgi.framework.internal.core.FrameworkProperties;
import org.eclipse.osgi.service.environment.Constants;
import org.eclipse.osgi.service.environment.EnvironmentInfo;
import org.eclipse.osgi.util.NLS;

/**
 * Internal class.
 */
public class EclipseEnvironmentInfo implements EnvironmentInfo {
	private static EclipseEnvironmentInfo singleton;
	private static String nl;
	private static String os;
	private static String ws;
	private static String arch;
	static String[] allArgs;
	static String[] frameworkArgs;
	static String[] appArgs;

	// While we recognize the SunOS operating system, we change
	// this internally to be Solaris.
	private static final String INTERNAL_OS_SUNOS = "SunOS"; //$NON-NLS-1$
	private static final String INTERNAL_OS_LINUX = "Linux"; //$NON-NLS-1$
	private static final String INTERNAL_OS_MACOSX = "Mac OS"; //$NON-NLS-1$
	private static final String INTERNAL_OS_AIX = "AIX"; //$NON-NLS-1$
	private static final String INTERNAL_OS_HPUX = "HP-UX"; //$NON-NLS-1$
	private static final String INTERNAL_OS_QNX = "QNX"; //$NON-NLS-1$

	// While we recognize the i386 architecture, we change
	// this internally to be x86.
	private static final String INTERNAL_ARCH_I386 = "i386"; //$NON-NLS-1$
	// While we recognize the amd64 architecture, we change
	// this internally to be x86_64.
	private static final String INTERNAL_AMD64 = "amd64"; //$NON-NLS-1$

	private EclipseEnvironmentInfo() {
		super();
		setupSystemContext();
	}

	public static EclipseEnvironmentInfo getDefault() {
		if (singleton == null)
			singleton = new EclipseEnvironmentInfo();
		return singleton;
	}

	public boolean inDevelopmentMode() {
		return FrameworkProperties.getProperty("osgi.dev") != null; //$NON-NLS-1$
	}

	public boolean inDebugMode() {
		return FrameworkProperties.getProperty("osgi.debug") != null; //$NON-NLS-1$
	}

	public String[] getCommandLineArgs() {
		return allArgs;
	}

	public String[] getFrameworkArgs() {
		return frameworkArgs;
	}

	public String[] getNonFrameworkArgs() {
		return appArgs;
	}

	public String getOSArch() {
		return arch;
	}

	public String getNL() {
		return nl;
	}

	public String getOS() {
		return os;
	}

	public String getWS() {
		return ws;
	}

	/**
	 * Initializes the execution context for this run of the platform.  The context
	 * includes information about the locale, operating system and window system.
	 * 
	 * NOTE: The OS, WS, and ARCH values should never be null. The executable should
	 * be setting these values and therefore this code path is obsolete for Eclipse
	 * when run from the executable.
	 */
	private static void setupSystemContext() {
		// if the user didn't set the locale with a command line argument then use the default.
		nl = FrameworkProperties.getProperty("osgi.nl"); //$NON-NLS-1$
		if (nl != null) {
			StringTokenizer tokenizer = new StringTokenizer(nl, "_"); //$NON-NLS-1$
			int segments = tokenizer.countTokens();
			try {
				Locale userLocale = null;
				switch (segments) {
					case 1 :
						// use the 2 arg constructor to maintain compatibility with 1.3.1
						userLocale = new Locale(tokenizer.nextToken(), ""); //$NON-NLS-1$
						break;
					case 2 :
						userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken());
						break;
					case 3 :
						userLocale = new Locale(tokenizer.nextToken(), tokenizer.nextToken(), tokenizer.nextToken());
						break;
					default :
						// if the user passed us in a bogus value then log a message and use the default
						System.err.println(NLS.bind(EclipseAdaptorMsg.error_badNL, nl)); 
						userLocale = Locale.getDefault();
						break;
				}
				Locale.setDefault(userLocale);
				// TODO what the heck is this for?? why not just use osgi.nl
				FrameworkProperties.setProperty("osgi.nl.user", nl); //$NON-NLS-1$
			} catch (NoSuchElementException e) {
				// fall through and use the default
			}
		}
		nl = Locale.getDefault().toString();
		FrameworkProperties.setProperty("osgi.nl", nl); //$NON-NLS-1$

		// if the user didn't set the operating system with a command line 
		// argument then use the default.
		os = FrameworkProperties.getProperty("osgi.os"); //$NON-NLS-1$
		if (os == null) {
			os = guessOS(FrameworkProperties.getProperty("os.name"));//$NON-NLS-1$);
			FrameworkProperties.setProperty("osgi.os", os); //$NON-NLS-1$
		}

		// if the user didn't set the window system with a command line 
		// argument then use the default.
		ws = FrameworkProperties.getProperty("osgi.ws"); //$NON-NLS-1$
		if (ws == null) {
			ws = guessWS(os);
			FrameworkProperties.setProperty("osgi.ws", ws); //$NON-NLS-1$
		}

		// if the user didn't set the system architecture with a command line 
		// argument then use the default.
		arch = FrameworkProperties.getProperty("osgi.arch"); //$NON-NLS-1$
		if (arch == null) {
			String name = FrameworkProperties.getProperty("os.arch");//$NON-NLS-1$
			// Map i386 architecture to x86
			if (name.equalsIgnoreCase(INTERNAL_ARCH_I386))
				arch = Constants.ARCH_X86;
			// Map amd64 architecture to x86_64
			else if (name.equalsIgnoreCase(INTERNAL_AMD64))
				arch = Constants.ARCH_X86_64;
			else
				arch = name;
			FrameworkProperties.setProperty("osgi.arch", arch); //$NON-NLS-1$			
		}
	}

	public static void setAllArgs(String[] allArgs) {
		if (EclipseEnvironmentInfo.allArgs == null)
			EclipseEnvironmentInfo.allArgs = allArgs;
	}

	public static void setAppArgs(String[] appArgs) {
		if (EclipseEnvironmentInfo.appArgs == null)
			EclipseEnvironmentInfo.appArgs = appArgs;
	}

	public static void setFrameworkArgs(String[] frameworkArgs) {
		if (EclipseEnvironmentInfo.frameworkArgs == null)
			EclipseEnvironmentInfo.frameworkArgs = frameworkArgs;
	}

	public static String guessWS(String os) {
		// setup default values for known OSes if nothing was specified
		if (os.equals(Constants.OS_WIN32))
			return Constants.WS_WIN32;
		if (os.equals(Constants.OS_LINUX))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_MACOSX))
			return Constants.WS_CARBON;
		if (os.equals(Constants.OS_HPUX))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_AIX))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_SOLARIS))
			return Constants.WS_MOTIF;
		if (os.equals(Constants.OS_QNX))
			return Constants.WS_PHOTON;
		return Constants.WS_UNKNOWN;
	}

	public static String guessOS(String osName) {
		// check to see if the OS name is "Windows 98" or some other
		// flavour which should be converted to win32.
		if (osName.regionMatches(true, 0, Constants.OS_WIN32, 0, 3))
			return Constants.OS_WIN32;
		// EXCEPTION: All mappings of SunOS convert to Solaris
		if (osName.equalsIgnoreCase(INTERNAL_OS_SUNOS))
			return Constants.OS_SOLARIS;
		if (osName.equalsIgnoreCase(INTERNAL_OS_LINUX))
			return Constants.OS_LINUX;
		if (osName.equalsIgnoreCase(INTERNAL_OS_QNX))
			return Constants.OS_QNX;
		if (osName.equalsIgnoreCase(INTERNAL_OS_AIX))
			return Constants.OS_AIX;
		if (osName.equalsIgnoreCase(INTERNAL_OS_HPUX))
			return Constants.OS_HPUX;
		// os.name on Mac OS can be either Mac OS or Mac OS X
		if (osName.regionMatches(true, 0, INTERNAL_OS_MACOSX, 0, INTERNAL_OS_MACOSX.length()))
			return Constants.OS_MACOSX;
		return Constants.OS_UNKNOWN;
	}
}
