/*
 * Copyright 2009 Google Inc.
 *
 * 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.google.gwt.dev.util;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

/**
 * Provides a platform and JDK-independent method of launching a browser
 * given a URI.
 *
 * <p>Portions derived from public-domain code at
 * <pre>http://www.centerkey.com/java/browser/</pre>
 */
public class BrowserLauncher {

  /**
   * A browser launcher that uses JDK 1.6 Desktop.browse support.
   */
  private static class Jdk16Launcher extends ReflectiveLauncher {

    /**
     * Create a Jdk16Launcher if supported.
     *
     * @throws UnsupportedOperationException if not supported
     */
    public Jdk16Launcher() throws UnsupportedOperationException {
      try {
        Class<?> desktopClass = Class.forName("java.awt.Desktop");
        browseMethod = desktopClass.getMethod("browse", URI.class);
        Method factory = desktopClass.getMethod("getDesktop");
        browseObject = factory.invoke(null);
        return;
      } catch (ClassNotFoundException e) {
        // not on JDK 1.6, try other methods
      } catch (NoSuchMethodException e) {
        // not on JDK 1.6, try other methods
      } catch (SecurityException e) {
        // ignore, try other methods
      } catch (IllegalArgumentException e) {
        // ignore, try other methods
      } catch (IllegalAccessException e) {
        // ignore, try other methods
      } catch (InvocationTargetException e) {
        // ignore, try other methods
      }
      throw new UnsupportedOperationException("no JDK 1.6 Desktop.browse");
    }

    @Override
    protected Object convertUrl(String url) throws URISyntaxException, MalformedURLException {
      return new URL(url).toURI();
    }
  }

  private interface Launcher {
    void browse(String url) throws IOException, URISyntaxException;
  }

  /**
   * Launch the default browser on Mac via FileManager openURL.
   */
  private static class MacLauncher extends ReflectiveLauncher {

    public MacLauncher() throws UnsupportedOperationException {
      Throwable caught = null;
      try {
        Class<?> fileManager = Class.forName("com.apple.eio.FileManager");
        browseMethod = fileManager.getMethod("openURL", String.class);
        browseObject = null;
        return;
      } catch (SecurityException e) {
        caught = e;
      } catch (ClassNotFoundException e) {
        caught = e;
      } catch (NoSuchMethodException e) {
        caught = e;
      }
      throw new UnsupportedOperationException("Can't get openURL", caught);
    }
  }

  /**
   * Interface for launching a URL in a browser, which uses reflection.
   *
   * <p>Subclass must set browseObject and browseMethod appropriately.
   */
  private abstract static class ReflectiveLauncher implements Launcher {

    protected Object browseObject;
    protected Method browseMethod;

    @Override
    public void browse(String url) throws IOException, URISyntaxException {
      Object arg = convertUrl(url);
      Throwable caught = null;
      try {
        browseMethod.invoke(browseObject, arg);
        return;
      } catch (InvocationTargetException e) {
        Throwable cause = e.getCause();
        if (cause instanceof IOException) {
          throw (IOException) cause;
        }
        caught = e;
      } catch (IllegalAccessException e) {
        caught = e;
      }
      throw new RuntimeException("Unexpected exception", caught);
    }

    /**
     * Convert the URL into another form if required.  The default
     * implementation simply returns the unmodified string.
     *
     * @param url URL in string form
     * @return the URL in the form needed for browseMethod
     * @throws URISyntaxException
     * @throws MalformedURLException
     */
    protected Object convertUrl(String url) throws URISyntaxException,
        MalformedURLException {
      return url;
    }
  }

  /**
   * Launch a browser by searching for a browser executable on the path.
   */
  private static class UnixExecBrowserLauncher implements Launcher {

    private static final String[] browsers = {
      "xdg-open", "gvfs-open", "gnome-open", "firefox", "opera", "konqueror",
      "chrome", "chromium", "epiphany", "seamonkey", "mozilla", "netscape",
      "galeon", "kazehakase",
    };

    private String browserExecutable;

    /**
     * Creates a launcher by searching for a suitable browser executable.
     * Assumes the presence of the "which" command.
     *
     * @throws UnsupportedOperationException if no suitable browser can be
     *           found.
     */
    public UnixExecBrowserLauncher() throws UnsupportedOperationException {
      for (String browser : browsers) {
        try {
          Process process = Runtime.getRuntime().exec(new String[] { "which",
              browser});
          if (process.waitFor() == 0) {
            browserExecutable = browser;
            return;
          }
        } catch (IOException e) {
          // ignore, try next one
        } catch (InterruptedException e) {
          // ignore, try next one
        }
      }
      throw new UnsupportedOperationException("no suitable browser found");
    }

    @Override
    public void browse(String url) throws IOException {
      Runtime.getRuntime().exec(new String[] { browserExecutable, url });
      // TODO(jat): do we need to wait for it to exit and check exit status?
      // That would be best for Firefox, but bad for some of the other browsers.
    }
  }

  /**
   * Launch the default browser on Windows via the URL protocol handler.
   */
  private static class WindowsLauncher implements Launcher {

    @Override
    public void browse(String url) throws IOException {
      Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
      // TODO(jat): do we need to wait for it to exit and check exit status?
    }
  }

  private static Launcher launcher;

  /**
   * Browse to a given URI.
   *
   * @param url
   * @throws IOException
   * @throws URISyntaxException
   */
  public static void browse(String url) throws IOException, URISyntaxException {
    if (launcher == null) {
      findLauncher();
    }
    launcher.browse(url);
  }

  /**
   * Main method so this can be run from the command line for testing.
   *
   * @param args URL to launch
   * @throws URISyntaxException
   * @throws IOException
   */
  public static void main(String[] args) throws IOException,
      URISyntaxException {
    if (args.length == 0) {
      System.err.println("Usage: BrowserLauncher url...");
      System.exit(1);
    }
    for (String url : args) {
      browse(url);
    }
  }

  /**
   * Initialize launcher to an appropriate one for the current platform/JDK.
   */
  private static void findLauncher() {
    try {
      launcher = new Jdk16Launcher();
      return;
    } catch (UnsupportedOperationException e) {
      // ignore and try other methods
    }
    String osName = System.getProperty("os.name");
    if (osName.startsWith("Mac OS")) {
      launcher = new MacLauncher();
    } else if (osName.startsWith("Windows")) {
      launcher = new WindowsLauncher();
    } else {
      launcher = new UnixExecBrowserLauncher();
      // let UnsupportedOperationException escape to caller
    }
  }
}
