package net.oni2.platformtools.applicationinvoker;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.Vector;

import net.oni2.platformtools.PlatformInformation;
import net.oni2.platformtools.PlatformInformation.Architecture;
import net.oni2.platformtools.PlatformInformation.Platform;
import net.oni2.platformtools.WinRegistry;
import net.oni2.platformtools.applicationinvoker.ApplicationInvoker;
import net.oni2.platformtools.applicationinvoker.ApplicationInvocationResult;

/**
 * @author Christian Illy
 */
public class DotNet {
	private static File mono = null;
	private static int isInst = -1;

	/**
	 * @return is a .NET implementation installed?
	 */
	public static boolean isInstalled() {
		if (isInst < 0) {
			isInst = 0;
			switch (PlatformInformation.getPlatform()) {
				case WIN:
					try {
						int view = WinRegistry.KEY_WOW64_32KEY;
						if (PlatformInformation.getArchitecture() == Architecture.AMD64)
							view = WinRegistry.KEY_WOW64_64KEY;

						Map<String, String> m = WinRegistry
								.readStringValues(
										WinRegistry.HKEY_LOCAL_MACHINE,
										"Software\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727",
										view);
						isInst = (m != null ? 1 : 0);
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					} catch (Exception e) {
						if (!e.getMessage()
								.equals("Registry access not supported (not a Windows OS?)."))
							e.printStackTrace();
					}
					break;
				case MACOS:
				case LINUX:
					Vector<String> params = new Vector<String>();
					params.add("mono");
					ApplicationInvocationResult res = null;
					try {
						res = ApplicationInvoker.executeAndWait(EExeType.OSBINARY, null, new File("which"), params, false);
					} catch (IOException e) {
						e.printStackTrace();
					} catch (ERuntimeNotInstalledException e) {
						e.printStackTrace();
					}
					if (res != null) {
						if (res.output.size() > 0) {
							if (res.output.get(0).startsWith("/")
									&& res.output.get(0).endsWith("mono")) {
								isInst = 1;
								mono = new File(res.output.get(0));
							}
						}
					}
					break;
				default:
					isInst = 0;
			}
		}
		return isInst == 1;
	}

	/**
	 * @return Get the .Net runtime executable name
	 */
	public static File getRuntimeExe() {
		if (PlatformInformation.getPlatform() != Platform.WIN)
			return mono;
		return null;
	}

}
