// Copyright (C) 2009 The Android Open Source Project
//
// 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.gerrit.pgm.http.jetty;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.servlet.GuiceFilter;
import com.google.inject.servlet.GuiceServletContextListener;

import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ThreadPool;
import org.eclipse.jgit.lib.Config;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.servlet.DispatcherType;

@Singleton
public class JettyServer {
  static class Lifecycle implements LifecycleListener {
    private final JettyServer server;

    @Inject
    Lifecycle(final JettyServer server) {
      this.server = server;
    }

    @Override
    public void start() {
      try {
        server.httpd.start();
      } catch (Exception e) {
        throw new IllegalStateException("Cannot start HTTP daemon", e);
      }
    }

    @Override
    public void stop() {
      try {
        server.httpd.stop();
        server.httpd.join();
      } catch (Exception e) {
        throw new IllegalStateException("Cannot stop HTTP daemon", e);
      }
    }
  }

  private final SitePaths site;
  private final Server httpd;

  private boolean reverseProxy;

  /** Location on disk where our WAR file was unpacked to. */
  private Resource baseResource;

  @Inject
  JettyServer(@GerritServerConfig final Config cfg, final SitePaths site,
      final JettyEnv env)
      throws MalformedURLException, IOException {
    this.site = site;

    httpd = new Server();
    httpd.setConnectors(listen(cfg));
    httpd.setThreadPool(threadPool(cfg));

    Handler app = makeContext(env, cfg);
    if (cfg.getBoolean("httpd", "requestlog", !reverseProxy)) {
      RequestLogHandler handler = new RequestLogHandler();
      handler.setRequestLog(new HttpLog(site, cfg));
      handler.setHandler(app);
      app = handler;
    }
    httpd.setHandler(app);

    httpd.setStopAtShutdown(false);
    httpd.setSendDateHeader(true);
    httpd.setSendServerVersion(false);
    httpd.setGracefulShutdown((int) MILLISECONDS.convert(1, SECONDS));
  }

  private Connector[] listen(final Config cfg) {
    // OpenID and certain web-based single-sign-on products can cause
    // some very long headers, especially in the Referer header. We
    // need to use a larger default header size to ensure we have
    // the space required.
    //
    final int requestHeaderSize =
        cfg.getInt("httpd", "requestheadersize", 16386);
    final URI[] listenUrls = listenURLs(cfg);
    final boolean reuseAddress = cfg.getBoolean("httpd", "reuseaddress", true);
    final int acceptors = cfg.getInt("httpd", "acceptorThreads", 2);
    final AuthType authType = ConfigUtil.getEnum(cfg, "auth", null, "type", AuthType.OPENID);

    reverseProxy = isReverseProxied(listenUrls);
    final Connector[] connectors = new Connector[listenUrls.length];
    for (int idx = 0; idx < listenUrls.length; idx++) {
      final URI u = listenUrls[idx];
      final int defaultPort;
      final SelectChannelConnector c;

      if (AuthType.CLIENT_SSL_CERT_LDAP.equals(authType) && ! "https".equals(u.getScheme())) {
        throw new IllegalArgumentException("Protocol '" + u.getScheme()
            + "' " + " not supported in httpd.listenurl '" + u
            + "' when auth.type = '" + AuthType.CLIENT_SSL_CERT_LDAP.name()
            + "'; only 'https' is supported");
      }

      if ("http".equals(u.getScheme())) {
        defaultPort = 80;
        c = new SelectChannelConnector();
      } else if ("https".equals(u.getScheme())) {
        SslContextFactory ssl = new SslContextFactory();
        final File keystore = getFile(cfg, "sslkeystore", "etc/keystore");
        String password = cfg.getString("httpd", null, "sslkeypassword");
        if (password == null) {
          password = "gerrit";
        }
        ssl.setKeyStorePath(keystore.getAbsolutePath());
        ssl.setTrustStore(keystore.getAbsolutePath());
        ssl.setKeyStorePassword(password);
        ssl.setTrustStorePassword(password);

        if (AuthType.CLIENT_SSL_CERT_LDAP.equals(authType)) {
          ssl.setNeedClientAuth(true);
        }

        defaultPort = 443;
        c = new SslSelectChannelConnector(ssl);

      } else if ("proxy-http".equals(u.getScheme())) {
        defaultPort = 8080;
        c = new SelectChannelConnector();
        c.setForwarded(true);

      } else if ("proxy-https".equals(u.getScheme())) {
        defaultPort = 8080;
        c = new SelectChannelConnector() {
          @Override
          public void customize(EndPoint endpoint, Request request)
              throws IOException {
            request.setScheme("https");
            super.customize(endpoint, request);
          }
        };
        c.setForwarded(true);

      } else {
        throw new IllegalArgumentException("Protocol '" + u.getScheme() + "' "
            + " not supported in httpd.listenurl '" + u + "';"
            + " only 'http', 'https', 'proxy-http, 'proxy-https'"
            + " are supported");
      }

      try {
        if (u.getHost() == null && (u.getAuthority().equals("*") //
            || u.getAuthority().startsWith("*:"))) {
          // Bind to all local addresses. Port wasn't parsed right by URI
          // due to the illegal host of "*" so replace with a legal name
          // and parse the URI.
          //
          final URI r =
              new URI(u.toString().replace('*', 'A')).parseServerAuthority();
          c.setHost(null);
          c.setPort(0 < r.getPort() ? r.getPort() : defaultPort);
        } else {
          final URI r = u.parseServerAuthority();
          c.setHost(r.getHost());
          c.setPort(0 < r.getPort() ? r.getPort() : defaultPort);
        }
      } catch (URISyntaxException e) {
        throw new IllegalArgumentException("Invalid httpd.listenurl " + u, e);
      }

      c.setRequestHeaderSize(requestHeaderSize);
      c.setAcceptors(acceptors);
      c.setReuseAddress(reuseAddress);
      c.setStatsOn(false);

      connectors[idx] = c;
    }
    return connectors;
  }

  static boolean isReverseProxied(final URI[] listenUrls) {
    for (URI u : listenUrls) {
      if ("http".equals(u.getScheme()) || "https".equals(u.getScheme())) {
        return false;
      }
    }
    return true;
  }

  static URI[] listenURLs(final Config cfg) {
    String[] urls = cfg.getStringList("httpd", null, "listenurl");
    if (urls.length == 0) {
      urls = new String[] {"http://*:8080/"};
    }

    final URI[] r = new URI[urls.length];
    for (int i = 0; i < r.length; i++) {
      final String s = urls[i];
      try {
        r[i] = new URI(s);
      } catch (URISyntaxException e) {
        throw new IllegalArgumentException("Invalid httpd.listenurl " + s, e);
      }
    }
    return r;
  }

  private File getFile(final Config cfg, final String name, final String def) {
    String path = cfg.getString("httpd", null, name);
    if (path == null || path.length() == 0) {
      path = def;
    }
    return site.resolve(path);
  }

  private ThreadPool threadPool(Config cfg) {
    final QueuedThreadPool pool = new QueuedThreadPool();
    pool.setName("HTTP");
    pool.setMinThreads(cfg.getInt("httpd", null, "minthreads", 5));
    pool.setMaxThreads(cfg.getInt("httpd", null, "maxthreads", 25));
    pool.setMaxQueued(cfg.getInt("httpd", null, "maxqueued", 50));
    return pool;
  }

  private Handler makeContext(final JettyEnv env, final Config cfg)
      throws MalformedURLException, IOException {
    final Set<String> paths = new HashSet<String>();
    for (URI u : listenURLs(cfg)) {
      String p = u.getPath();
      if (p == null || p.isEmpty()) {
        p = "/";
      }
      while (1 < p.length() && p.endsWith("/")) {
        p = p.substring(0, p.length() - 1);
      }
      paths.add(p);
    }

    final List<ContextHandler> all = new ArrayList<ContextHandler>();
    for (String path : paths) {
      all.add(makeContext(path, env));
    }

    if (all.size() == 1) {
      // If we only have one context path in our web space, return it
      // without any wrapping so Jetty has less work to do per-request.
      //
      return all.get(0);
    } else {
      // We have more than one path served out of this container so
      // combine them in a handler which supports dispatching to the
      // individual contexts.
      //
      final ContextHandlerCollection r = new ContextHandlerCollection();
      r.setHandlers(all.toArray(new Handler[0]));
      return r;
    }
  }

  private ContextHandler makeContext(final String contextPath,
      final JettyEnv env) throws MalformedURLException, IOException {
    final ServletContextHandler app = new ServletContextHandler();

    // This enables the use of sessions in Jetty, feature available
    // for Gerrit plug-ins to enable user-level sessions.
    //
    app.setSessionHandler(new SessionHandler());

    // This is the path we are accessed by clients within our domain.
    //
    app.setContextPath(contextPath);

    // Serve static resources directly from our JAR. This way we don't
    // need to unpack them into yet another temporary directory prior to
    // serving to clients.
    //
    app.setBaseResource(getBaseResource());

    // Perform the same binding as our web.xml would do, but instead
    // of using the listener to create the injector pass the one we
    // already have built.
    //
    GuiceFilter filter = env.webInjector.getInstance(GuiceFilter.class);
    app.addFilter(new FilterHolder(filter), "/*", EnumSet.of(
        DispatcherType.REQUEST,
        DispatcherType.ASYNC));
    app.addEventListener(new GuiceServletContextListener() {
      @Override
      protected Injector getInjector() {
        return env.webInjector;
      }
    });

    // Jetty requires at least one servlet be bound before it will
    // bother running the filter above. Since the filter has all
    // of our URLs except the static resources, the only servlet
    // we need to bind is the default static resource servlet from
    // the Jetty container.
    //
    final ServletHolder ds = app.addServlet(DefaultServlet.class, "/");
    ds.setInitParameter("dirAllowed", "false");
    ds.setInitParameter("redirectWelcome", "false");
    ds.setInitParameter("useFileMappedBuffer", "false");
    ds.setInitParameter("gzip", "true");

    app.setWelcomeFiles(new String[0]);
    return app;
  }

  private Resource getBaseResource() throws IOException {
    if (baseResource == null) {
      try {
        baseResource = unpackWar();
      } catch (FileNotFoundException err) {
        if (err.getMessage() == GerritLauncher.NOT_ARCHIVED) {
          baseResource = useDeveloperBuild();
        } else {
          throw err;
        }
      }
    }
    return baseResource;
  }

  private Resource unpackWar() throws IOException {
    final File srcwar = GerritLauncher.getDistributionArchive();

    // Obtain our local temporary directory, but it comes back as a file
    // so we have to switch it to be a directory post creation.
    //
    File dstwar = GerritLauncher.createTempFile("gerrit_", "war");
    if (!dstwar.delete() || !dstwar.mkdir()) {
      throw new IOException("Cannot mkdir " + dstwar.getAbsolutePath());
    }

    // Jetty normally refuses to serve out of a symlinked directory, as
    // a security feature. Try to resolve out any symlinks in the path.
    //
    try {
      dstwar = dstwar.getCanonicalFile();
    } catch (IOException e) {
      dstwar = dstwar.getAbsoluteFile();
    }

    final ZipFile zf = new ZipFile(srcwar);
    try {
      final Enumeration<? extends ZipEntry> e = zf.entries();
      while (e.hasMoreElements()) {
        final ZipEntry ze = e.nextElement();
        final String name = ze.getName();

        if (ze.isDirectory()) continue;
        if (name.startsWith("WEB-INF/")) continue;
        if (name.startsWith("META-INF/")) continue;
        if (name.startsWith("com/google/gerrit/launcher/")) continue;
        if (name.equals("Main.class")) continue;

        final File rawtmp = new File(dstwar, name);
        mkdir(rawtmp.getParentFile());
        rawtmp.deleteOnExit();

        final FileOutputStream rawout = new FileOutputStream(rawtmp);
        try {
          final InputStream in = zf.getInputStream(ze);
          try {
            final byte[] buf = new byte[4096];
            int n;
            while ((n = in.read(buf, 0, buf.length)) > 0) {
              rawout.write(buf, 0, n);
            }
          } finally {
            in.close();
          }
        } finally {
          rawout.close();
        }
      }
    } finally {
      zf.close();
    }

    return Resource.newResource(dstwar.toURI());
  }

  private void mkdir(final File dir) throws IOException {
    if (!dir.isDirectory()) {
      mkdir(dir.getParentFile());
      if (!dir.mkdir())
        throw new IOException("Cannot mkdir " + dir.getAbsolutePath());
      dir.deleteOnExit();
    }
  }

  private Resource useDeveloperBuild() throws IOException {
    // Find ourselves in the CLASSPATH. We should be a loose class file.
    //
    URL u = getClass().getResource(getClass().getSimpleName() + ".class");
    if (u == null) {
      throw new FileNotFoundException("Cannot find web application root");
    }
    if (!"file".equals(u.getProtocol())) {
      throw new FileNotFoundException("Cannot find web root from " + u);
    }

    // Pop up to the top level classes folder that contains us.
    //
    File dir = new File(u.getPath());
    String myName = getClass().getName();
    for (;;) {
      int dot = myName.lastIndexOf('.');
      if (dot < 0) {
        dir = dir.getParentFile();
        break;
      }
      myName = myName.substring(0, dot);
      dir = dir.getParentFile();
    }

    // We should be in a Maven style output, that is $jar/target/classes.
    //
    if (!dir.getName().equals("classes")) {
      throw new FileNotFoundException("Cannot find web root from " + u);
    }
    dir = dir.getParentFile(); // pop classes
    if (!dir.getName().equals("target")) {
      throw new FileNotFoundException("Cannot find web root from " + u);
    }
    dir = dir.getParentFile(); // pop target
    dir = dir.getParentFile(); // pop the module we are in

    // Drop down into gerrit-gwtui to find the WAR assets we need.
    //
    dir = new File(new File(dir, "gerrit-gwtui"), "target");
    final File[] entries = dir.listFiles();
    if (entries == null) {
      throw new FileNotFoundException("No " + dir);
    }
    for (File e : entries) {
      if (e.isDirectory() /* must be a directory */
          && e.getName().startsWith("gerrit-gwtui-")
          && new File(e, "gerrit_ui/gerrit_ui.nocache.js").isFile()) {
        return Resource.newResource(e.toURI());
      }
    }
    throw new FileNotFoundException("No " + dir + "/gerrit-gwtui-*");
  }
}
