// 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.

// CGI environment and execution management portions are:
//
// ========================================================================
// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses.
// ========================================================================

package com.google.gerrit.httpd.gitweb;

import com.google.gerrit.common.data.GerritConfig;
import com.google.gerrit.httpd.GitWebConfig;
import com.google.gerrit.launcher.GerritLauncher;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.LocalDiskRepositoryManager;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** Invokes {@code gitweb.cgi} for the project given in {@code p}. */
@SuppressWarnings("serial")
@Singleton
class GitWebServlet extends HttpServlet {
  private static final Logger log =
      LoggerFactory.getLogger(GitWebServlet.class);

  private final Set<String> deniedActions;
  private final int bufferSize = 8192;
  private final File gitwebCgi;
  private final LocalDiskRepositoryManager repoManager;
  private final ProjectControl.Factory projectControl;
  private final EnvList _env;

  @Inject
  GitWebServlet(final LocalDiskRepositoryManager repoManager,
      final ProjectControl.Factory projectControl, final SitePaths site,
      final GerritConfig gerritConfig, final GitWebConfig gitWebConfig)
      throws IOException {
    this.repoManager = repoManager;
    this.projectControl = projectControl;
    this.gitwebCgi = gitWebConfig.getGitwebCGI();
    this.deniedActions = new HashSet<String>();

    deniedActions.add("forks");
    deniedActions.add("opml");
    deniedActions.add("project_list");
    deniedActions.add("project_index");

    _env = new EnvList();
    makeSiteConfig(site, gerritConfig);

    if (!_env.envMap.containsKey("SystemRoot")) {
      String os = System.getProperty("os.name");
      if (os != null && os.toLowerCase().indexOf("windows") != -1) {
        String sysroot = System.getenv("SystemRoot");
        if (sysroot == null || sysroot.isEmpty()) {
          sysroot = "C:\\WINDOWS";
        }
        _env.set("SystemRoot", sysroot);
      }
    }

    if (!_env.envMap.containsKey("PATH")) {
      _env.set("PATH", System.getenv("PATH"));
    }
  }

  private void makeSiteConfig(final SitePaths site,
      final GerritConfig gerritConfig) throws IOException {
    final File myconf = GerritLauncher.createTempFile("gitweb_config", ".perl");

    // To make our configuration file only readable or writable by us;
    // this reduces the chances of someone tampering with the file.
    //
    myconf.setWritable(false, false /* all */);
    myconf.setReadable(false, false /* all */);
    myconf.setExecutable(false, false /* all */);

    myconf.setWritable(true, true /* owner only */);
    myconf.setReadable(true, true /* owner only */);

    _env.set("GIT_DIR", ".");
    _env.set("GITWEB_CONFIG", myconf.getAbsolutePath());

    final PrintWriter p = new PrintWriter(new FileWriter(myconf));
    try {
      p.print("# Autogenerated by Gerrit Code Review \n");
      p.print("# DO NOT EDIT\n");
      p.print("\n");

      // We are mounted at the same level in the context as the main
      // UI, so we can include the same header and footer scheme.
      //
      final File hdr = site.site_header;
      if (hdr.isFile()) {
        p.print("$site_header = " + quoteForPerl(hdr) + ";\n");
      }
      final File ftr = site.site_footer;
      if (ftr.isFile()) {
        p.print("$site_footer = " + quoteForPerl(ftr) + ";\n");
      }

      // Top level should return to Gerrit's UI.
      //
      p.print("$home_link = $ENV{'GERRIT_CONTEXT_PATH'};\n");
      p.print("$home_link_str = 'Code Review';\n");

      p.print("$favicon = 'favicon.ico';\n");
      p.print("$logo = 'gitweb-logo.png';\n");
      p.print("@stylesheets = ('gitweb-default.css');\n");
      final File css = site.site_css;
      if (css.isFile()) {
        p.print("push @stylesheets, 'gitweb-site.css';\n");
      }

      // Try to make the title match Gerrit's normal window title
      // scheme of host followed by 'Code Review'.
      //
      p.print("$site_name = $home_link_str;\n");
      p.print("$site_name = qq{$1 $site_name} if ");
      p.print("$ENV{'SERVER_NAME'} =~ m,^([^.]+(?:\\.[^.]+)?)(?:\\.|$),;\n");

      // Assume by default that XSS is a problem, and try to prevent it.
      //
      p.print("$prevent_xss = 1;\n");

      // Generate URLs using smart http://
      //
      p.print("{\n");
      p.print("  my $secure = $ENV{'HTTPS'} =~ /^ON$/i;\n");
      p.print("  my $http_url = $secure ? 'https://' : 'http://';\n");
      p.print("  $http_url .= qq{$ENV{'GERRIT_USER_NAME'}@}\n");
      p.print("    unless $ENV{'GERRIT_ANONYMOUS_READ'};\n");
      p.print("  $http_url .= $ENV{'SERVER_NAME'};\n");
      p.print("  $http_url .= qq{:$ENV{'SERVER_PORT'}}\n");
      p.print("    if (( $secure && $ENV{'SERVER_PORT'} != 443)\n");
      p.print("     || (!$secure && $ENV{'SERVER_PORT'} != 80)\n");
      p.print("    );\n");
      p.print("  $http_url .= qq{$ENV{'GERRIT_CONTEXT_PATH'}p};\n");
      p.print("  push @git_base_url_list, $http_url;\n");
      p.print("}\n");

      // Generate URLs using anonymous git://
      //
      if (gerritConfig.getGitDaemonUrl() != null) {
        String url = gerritConfig.getGitDaemonUrl();
        if (url.endsWith("/")) {
          url = url.substring(0, url.length() - 1);
        }
        p.print("if ($ENV{'GERRIT_ANONYMOUS_READ'}) {\n");
        p.print("  push @git_base_url_list, ");
        p.print(quoteForPerl(url));
        p.print(";\n");
        p.print("}\n");
      }

      // Generate URLs using authenticated ssh://
      //
      if (gerritConfig.getSshdAddress() != null) {
        String sshAddr = gerritConfig.getSshdAddress();
        p.print("if ($ENV{'GERRIT_USER_NAME'}) {\n");
        p.print("  push @git_base_url_list, join('', 'ssh://'");
        p.print(", $ENV{'GERRIT_USER_NAME'}");
        p.print(", '@'");
        if (sshAddr.startsWith("*:") || "".equals(sshAddr)) {
          p.print(", $ENV{'SERVER_NAME'}");
        }
        if (sshAddr.startsWith("*")) {
          sshAddr = sshAddr.substring(1);
        }
        p.print(", " + quoteForPerl(sshAddr));
        p.print(");\n");
        p.print("}\n");
      }

      // If the administrator has created a site-specific gitweb_config,
      // load that before we perform any final overrides.
      //
      final File sitecfg = site.site_gitweb;
      if (sitecfg.isFile()) {
        p.print("$GITWEB_CONFIG = " + quoteForPerl(sitecfg) + ";\n");
        p.print("if (-e $GITWEB_CONFIG) {\n");
        p.print("  do " + quoteForPerl(sitecfg) + ";\n");
        p.print("}\n");
      }

      final File root = repoManager.getBasePath();
      p.print("$projectroot = " + quoteForPerl(root) + ";\n");

      // Link from commits to their matching review record.
      //
      p.print("if ($cgi->param('a') =~ /^(commit|commitdiff)$/) {\n");
      p.print("  my $h = $cgi->param('h');\n");
      p.print("  my $r = qq{$ENV{'GERRIT_CONTEXT_PATH'}#q,$h,n,z};");
      p.print("  push @{$feature{'actions'}{'default'}},\n");
      p.print("    ('review',$r,'commitdiff');\n");
      p.print("} elsif ($cgi->param('a') =~ /^(tree|blob)$/) {\n");
      p.print("  my $h = $cgi->param('hb');\n");
      p.print("  my $r = qq{$ENV{'GERRIT_CONTEXT_PATH'}#q,$h,n,z};");
      p.print("  push @{$feature{'actions'}{'default'}},\n");
      p.print("    ('review',$r,'commitdiff');\n");
      p.print("}\n");

      // Permit exporting only the project we were started for.
      // We use the name under $projectroot in case symlinks
      // were involved in the path.
      //
      p.print("$export_auth_hook = sub {\n");
      p.print("    my $dir = shift;\n");
      p.print("    my $name = $ENV{'GERRIT_PROJECT_NAME'};\n");
      p.print("    my $allow = qq{$projectroot/$name.git};\n");
      p.print("    return $dir eq $allow;\n");
      p.print("  };\n");

      // Do not allow the administrator to enable path info, its
      // not a URL format we currently support.
      //
      p.print("$feature{'pathinfo'}{'override'} = 0;\n");
      p.print("$feature{'pathinfo'}{'default'} = [0];\n");

      // We don't do forking, so don't allow it to be enabled.
      //
      p.print("$feature{'forks'}{'override'} = 0;\n");
      p.print("$feature{'forks'}{'default'} = [0];\n");
    } finally {
      p.close();
    }

    myconf.setReadOnly();
  }

  private String quoteForPerl(File value) {
    return quoteForPerl(value.getAbsolutePath());
  }

  private String quoteForPerl(String value) {
    if (value == null || value.isEmpty()) {
      return "''";
    }
    if (!value.contains("'")) {
      return "'" + value + "'";
    }
    if (!value.contains("{") && !value.contains("}")) {
      return "q{" + value + "}";
    }
    throw new IllegalArgumentException("Cannot quote in Perl: " + value);
  }

  @Override
  protected void service(final HttpServletRequest req,
      final HttpServletResponse rsp) throws IOException {
    if (req.getQueryString() == null || req.getQueryString().isEmpty()) {
      // No query string? They want the project list, which we don't
      // currently support. Return to Gerrit's own web UI.
      //
      rsp.sendRedirect(req.getContextPath() + "/");
      return;
    }

    final Map<String, String> params = getParameters(req);
    if (deniedActions.contains(params.get("a"))) {
      rsp.sendError(HttpServletResponse.SC_FORBIDDEN);
      return;
    }

    String name = params.get("p");
    if (name == null) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }
    if (name.endsWith(".git")) {
      name = name.substring(0, name.length() - 4);
    }

    final ProjectControl project;
    try {
      final Project.NameKey nameKey = new Project.NameKey(name);
      project = projectControl.validateFor(nameKey);
    } catch (NoSuchProjectException e) {
      rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
      return;
    }

    final Repository repo;
    try {
      repo = repoManager.openRepository(name);
    } catch (RepositoryNotFoundException e) {
      getServletContext().log("Cannot open repository", e);
      rsp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
      return;
    }

    rsp.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
    rsp.setHeader("Pragma", "no-cache");
    rsp.setHeader("Cache-Control", "no-cache, must-revalidate");
    exec(req, rsp, project, repo);
  }

  private static Map<String, String> getParameters(final HttpServletRequest req)
      throws UnsupportedEncodingException {
    final Map<String, String> params = new HashMap<String, String>();
    for (final String pair : req.getQueryString().split(";")) {
      final int eq = pair.indexOf('=');
      if (0 < eq) {
        String name = pair.substring(0, eq);
        String value = pair.substring(eq + 1);

        name = URLDecoder.decode(name, "UTF-8");
        value = URLDecoder.decode(value, "UTF-8");
        params.put(name, value);
      }
    }
    return params;
  }

  private void exec(final HttpServletRequest req,
      final HttpServletResponse rsp, final ProjectControl project,
      final Repository repo) throws IOException {
    final Process proc =
        Runtime.getRuntime().exec(new String[] {gitwebCgi.getAbsolutePath()},
            makeEnv(req, project), repo.getDirectory());

    copyStderrToLog(proc.getErrorStream());
    if (0 < req.getContentLength()) {
      copyContentToCGI(req, proc.getOutputStream());
    } else {
      proc.getOutputStream().close();
    }

    try {
      final InputStream in;

      in = new BufferedInputStream(proc.getInputStream(), bufferSize);
      try {
        readCgiHeaders(rsp, in);

        final OutputStream out = rsp.getOutputStream();
        try {
          final byte[] buf = new byte[bufferSize];
          int n;
          while ((n = in.read(buf)) > 0) {
            out.write(buf, 0, n);
          }
        } finally {
          out.close();
        }
      } finally {
        in.close();
      }
    } catch (IOException e) {
      // The browser has probably closed its input stream. We don't
      // want to continue executing this request.
      //
      proc.destroy();
      return;
    }

    try {
      proc.waitFor();

      final int status = proc.exitValue();
      if (0 != status) {
        log.error("Non-zero exit status (" + status + ") from " + gitwebCgi);
        if (!rsp.isCommitted()) {
          rsp.sendError(500);
        }
      }
    } catch (InterruptedException ie) {
      log.debug("CGI: interrupted waiting for CGI to terminate");
    }
  }

  private String[] makeEnv(final HttpServletRequest req,
      final ProjectControl project) {
    final EnvList env = new EnvList(_env);
    final int contentLength = Math.max(0, req.getContentLength());

    // These ones are from "The WWW Common Gateway Interface Version 1.1"
    //
    env.set("AUTH_TYPE", req.getAuthType());
    env.set("CONTENT_LENGTH", Integer.toString(contentLength));
    env.set("CONTENT_TYPE", req.getContentType());
    env.set("GATEWAY_INTERFACE", "CGI/1.1");
    env.set("PATH_INFO", req.getPathInfo());
    env.set("PATH_TRANSLATED", null);
    env.set("QUERY_STRING", req.getQueryString());
    env.set("REMOTE_ADDR", req.getRemoteAddr());
    env.set("REMOTE_HOST", req.getRemoteHost());
    env.set("HTTPS", req.isSecure() ? "ON" : "OFF");

    // The identity information reported about the connection by a
    // RFC 1413 [11] request to the remote agent, if
    // available. Servers MAY choose not to support this feature, or
    // not to request the data for efficiency reasons.
    // "REMOTE_IDENT" => "NYI"
    //
    env.set("REQUEST_METHOD", req.getMethod());
    env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath());
    env.set("SCRIPT_FILENAME", gitwebCgi.getAbsolutePath());
    env.set("SERVER_NAME", req.getServerName());
    env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
    env.set("SERVER_PROTOCOL", req.getProtocol());
    env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());

    final Enumeration<String> hdrs = enumerateHeaderNames(req);
    while (hdrs.hasMoreElements()) {
      final String name = hdrs.nextElement();
      final String value = req.getHeader(name);
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
    }

    env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
    env.set("GERRIT_PROJECT_NAME", project.getProject().getName());

    if (project.forAnonymousUser().isVisible()) {
      env.set("GERRIT_ANONYMOUS_READ", "1");
    }

    String remoteUser = null;
    if (project.getCurrentUser() instanceof IdentifiedUser) {
      final IdentifiedUser u = (IdentifiedUser) project.getCurrentUser();
      final String user = u.getUserName();
      env.set("GERRIT_USER_NAME", user);
      if (user != null && !user.isEmpty()) {
        remoteUser = user;
      } else {
        remoteUser = "account-" + u.getAccountId();
      }
    }
    env.set("REMOTE_USER", remoteUser);

    return env.getEnvArray();
  }

  private void copyContentToCGI(final HttpServletRequest req,
      final OutputStream dst) throws IOException {
    final int contentLength = req.getContentLength();
    final InputStream src = req.getInputStream();
    new Thread(new Runnable() {
      public void run() {
        try {
          try {
            final byte[] buf = new byte[bufferSize];
            int remaining = contentLength;
            while (0 < remaining) {
              final int max = Math.max(buf.length, remaining);
              final int n = src.read(buf, 0, max);
              if (n < 0) {
                throw new EOFException("Expected " + remaining + " more bytes");
              }
              dst.write(buf, 0, n);
              remaining -= n;
            }
          } finally {
            dst.close();
          }
        } catch (IOException e) {
          log.debug("Unexpected error copying input to CGI", e);
        }
      }
    }, "GitWeb-InputFeeder").start();
  }

  private void copyStderrToLog(final InputStream in) {
    new Thread(new Runnable() {
      public void run() {
        try {
          final BufferedReader br =
              new BufferedReader(new InputStreamReader(in, "ISO-8859-1"));
          try {
            String line;
            while ((line = br.readLine()) != null) {
              log.error("CGI: " + line);
            }
          } finally {
            br.close();
          }
        } catch (IOException e) {
          log.debug("Unexpected error copying stderr from CGI", e);
        }
      }
    }, "GitWeb-ErrorLogger").start();
  }

  @SuppressWarnings("unchecked")
  private static Enumeration<String> enumerateHeaderNames(HttpServletRequest req) {
    return req.getHeaderNames();
  }

  private void readCgiHeaders(HttpServletResponse res, final InputStream in)
      throws IOException {
    String line;
    while (!(line = readLine(in)).isEmpty()) {
      if (line.startsWith("HTTP")) {
        // CGI believes it is a non-parsed-header CGI. We refuse
        // to support that here so abort.
        //
        throw new IOException("NPH CGI not supported: " + line);
      }

      final int sep = line.indexOf(':');
      if (sep < 0) {
        throw new IOException("CGI returned invalid header: " + line);
      }

      final String key = line.substring(0, sep).trim();
      final String value = line.substring(sep + 1).trim();
      if ("Location".equalsIgnoreCase(key)) {
        res.sendRedirect(value);

      } else if ("Status".equalsIgnoreCase(key)) {
        final String[] token = value.split(" ");
        final int status = Integer.parseInt(token[0]);
        res.setStatus(status);

      } else {
        res.addHeader(key, value);
      }
    }
  }

  private String readLine(final InputStream in) throws IOException {
    final StringBuilder buf = new StringBuilder();
    int b;
    while ((b = in.read()) != -1 && b != '\n') {
      buf.append((char) b);
    }
    return buf.toString().trim();
  }

  /** private utility class that manages the Environment passed to exec. */
  private static class EnvList {
    private Map<String, String> envMap;

    EnvList() {
      envMap = new HashMap<String, String>();
    }

    EnvList(final EnvList l) {
      envMap = new HashMap<String, String>(l.envMap);
    }

    /** Set a name/value pair, null values will be treated as an empty String */
    public void set(final String name, String value) {
      if (value == null) {
        value = "";
      }
      envMap.put(name, name + "=" + value);
    }

    /** Get representation suitable for passing to exec. */
    public String[] getEnvArray() {
      return envMap.values().toArray(new String[envMap.size()]);
    }

    @Override
    public String toString() {
      return envMap.toString();
    }
  }
}
