/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.rt.execution.application;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author ven
 * @noinspection HardCodedStringLiteral
 */
public class AppMain {
  private static final String PROPERTY_PORT_NUMBER = "idea.launcher.port";
  private static final String PROPERTY_BINPATH = "idea.launcher.bin.path";

  private static final String JAVAFX_LAUNCHER = "com.sun.javafx.application.LauncherImpl";
  private static final String LAUNCH_APPLICATION_METHOD_NAME = "launchApplication";

  private static native void triggerControlBreak();

  static {
    String binPath = System.getProperty(PROPERTY_BINPATH) + File.separator;
    final String osName = System.getProperty("os.name").toLowerCase();
    String arch = System.getProperty("os.arch").toLowerCase();
    String libPath = null;
    if (osName.startsWith("windows")) {
      if (arch.equals("amd64")) {
        libPath = binPath + "breakgen64.dll";
      }
      else {
        libPath = binPath + "breakgen.dll";
      }
    } else if (osName.startsWith("linux")) {
      if (arch.equals("amd64")) {
        libPath = binPath + "libbreakgen64.so";
      } else {
        libPath = binPath + "libbreakgen.so";
      }
    } else if (osName.startsWith("mac")) {
      if (arch.endsWith("64")) {
        libPath = binPath + "libbreakgen64.jnilib";
      } else {
        libPath = binPath + "libbreakgen.jnilib";
      }
    }

    try {
      if (libPath != null) {
        System.load(libPath);
      }
    }
    catch (UnsatisfiedLinkError e) {
      //Do nothing, unknown os or some other error => no ctrl-break is available
    }
  }

  public static void main(String[] args) throws Throwable {

    final int portNumber = Integer.getInteger(PROPERTY_PORT_NUMBER).intValue();
    Thread t = new Thread(
      new Runnable() {
        public void run() {
          try {
            ServerSocket socket = new ServerSocket(portNumber);
            Socket client = socket.accept();
            BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            while (true) {
              String msg = reader.readLine();

              if ("TERM".equals(msg)){
                return;
              }
              else if ("BREAK".equals(msg)) {
                triggerControlBreak();
              }
              else if ("STOP".equals(msg)) {
                System.exit(1);
              }
            }
          } catch (IOException ignored) {
          } catch (IllegalArgumentException ignored) {
          } catch (SecurityException ignored) {
          }
        }
      }, "Monitor Ctrl-Break");
    try {
      t.setDaemon(true);
      t.start();
    } catch (Exception ignored) {}

    String mainClass = args[0];
    String[] parms = new String[args.length - 1];
    for (int j = 1; j < args.length; j++) {
      parms[j - 1] = args[j];
    }
    final Class appClass = Class.forName(mainClass);
    Method m;
    try {
      m = appClass.getMethod("main", new Class[]{parms.getClass()});
    }
    catch (NoSuchMethodException e) {
      if (!startJavaFXApplication(parms, appClass)) {
        throw e;
      }
      return;
    }

    if (!Modifier.isStatic(m.getModifiers())) {
      System.err.println("main method should be static");
      return;
    }
    try {
      ensureAccess(m);
      m.invoke(null, new Object[]{parms});
    } catch (InvocationTargetException ite) {
      throw ite.getTargetException();
    }
  }

  private static boolean startJavaFXApplication(String[] parms, Class appClass) throws NoSuchMethodException {
    try {
      //check in launch method for application class in the stack trace leads to this hack here
      final Method launchApplication = Class.forName(JAVAFX_LAUNCHER).getMethod(LAUNCH_APPLICATION_METHOD_NAME,
                                                                                new Class[]{appClass.getClass(), parms.getClass()});
      launchApplication.invoke(null, new Object[] {appClass, parms});
      return true;
    }
    catch (Throwable e) {
      return false;
    }
  }

  private static void ensureAccess(Object reflectionObject) {
    // need to call setAccessible here in order to be able to launch package-local classes
    // calling setAccessible() via reflection because the method is missing from java version 1.1.x
    final Class aClass = reflectionObject.getClass();
    try {
      final Method setAccessibleMethod = aClass.getMethod("setAccessible", new Class[] {boolean.class});
      setAccessibleMethod.invoke(reflectionObject, new Object[] {Boolean.TRUE});
    }
    catch (Exception e) {
      // the method not found
    }
  }
}
