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

import static com.google.gerrit.common.FileUtil.chmod;
import static com.google.gerrit.pgm.init.InitUtil.die;
import static com.google.gerrit.pgm.init.InitUtil.domainOf;
import static com.google.gerrit.pgm.init.InitUtil.isAnyAddress;
import static com.google.gerrit.pgm.init.InitUtil.toURI;

import com.google.gerrit.pgm.util.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
import com.google.gwtjsonrpc.server.SignedToken;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/** Initialize the {@code httpd} configuration section. */
@Singleton
class InitHttpd implements InitStep {
  private final ConsoleUI ui;
  private final SitePaths site;
  private final InitFlags flags;
  private final Section httpd;
  private final Section gerrit;

  @Inject
  InitHttpd(final ConsoleUI ui, final SitePaths site, final InitFlags flags,
      final Section.Factory sections) {
    this.ui = ui;
    this.site = site;
    this.flags = flags;
    this.httpd = sections.get("httpd", null);
    this.gerrit = sections.get("gerrit", null);
  }

  public void run() throws IOException, InterruptedException {
    ui.header("HTTP Daemon");

    boolean proxy = false, ssl = false;
    String address = "*";
    int port = -1;
    String context = "/";
    String listenUrl = httpd.get("listenUrl");
    if (listenUrl != null && !listenUrl.isEmpty()) {
      try {
        final URI uri = toURI(listenUrl);
        proxy = uri.getScheme().startsWith("proxy-");
        ssl = uri.getScheme().endsWith("https");
        address = isAnyAddress(new URI(listenUrl)) ? "*" : uri.getHost();
        port = uri.getPort();
        context = uri.getPath();
      } catch (URISyntaxException e) {
        System.err.println("warning: invalid httpd.listenUrl " + listenUrl);
      }
    }

    proxy = ui.yesno(proxy, "Behind reverse proxy");

    if (proxy) {
      ssl = ui.yesno(ssl, "Proxy uses SSL (https://)");
      context = ui.readString(context, "Subdirectory on proxy server");
    } else {
      ssl = ui.yesno(ssl, "Use SSL (https://)");
      context = "/";
    }

    address = ui.readString(address, "Listen on address");

    if (port < 0) {
      if (proxy) {
        port = 8081;
      } else if (ssl) {
        port = 8443;
      } else {
        port = 8080;
      }
    }
    port = ui.readInt(port, "Listen on port");

    final StringBuilder urlbuf = new StringBuilder();
    urlbuf.append(proxy ? "proxy-" : "");
    urlbuf.append(ssl ? "https" : "http");
    urlbuf.append("://");
    urlbuf.append(address);
    if (0 <= port) {
      urlbuf.append(":");
      urlbuf.append(port);
    }
    urlbuf.append(context);
    httpd.set("listenUrl", urlbuf.toString());

    URI uri;
    try {
      uri = toURI(httpd.get("listenUrl"));
      if (uri.getScheme().startsWith("proxy-")) {
        // If its a proxy URL, assume the reverse proxy is on our system
        // at the protocol standard ports (so omit the ports from the URL).
        //
        String s = uri.getScheme().substring("proxy-".length());
        uri = new URI(s + "://" + uri.getHost() + uri.getPath());
      }
    } catch (URISyntaxException e) {
      throw die("invalid httpd.listenUrl");
    }
    gerrit.string("Canonical URL", "canonicalWebUrl", uri.toString());
    generateSslCertificate();
  }

  private void generateSslCertificate() throws IOException,
      InterruptedException {
    final String listenUrl = httpd.get("listenUrl");

    if (!listenUrl.startsWith("https://")) {
      // We aren't responsible for SSL processing.
      //
      return;
    }

    String hostname;
    try {
      String url = gerrit.get("canonicalWebUrl");
      if (url == null || url.isEmpty()) {
        url = listenUrl;
      }
      hostname = toURI(url).getHost();
    } catch (URISyntaxException e) {
      System.err.println("Invalid httpd.listenUrl, not checking certificate");
      return;
    }

    final File store = site.ssl_keystore;
    if (!ui.yesno(!store.exists(), "Create new self-signed SSL certificate")) {
      return;
    }

    String ssl_pass = flags.sec.getString("http", null, "sslKeyPassword");
    if (ssl_pass == null || ssl_pass.isEmpty()) {
      ssl_pass = SignedToken.generateRandomKey();
      flags.sec.setString("httpd", null, "sslKeyPassword", ssl_pass);
    }

    hostname = ui.readString(hostname, "Certificate server name");
    final String validity =
        ui.readString("365", "Certificate expires in (days)");

    final String dname =
        "CN=" + hostname + ",OU=Gerrit Code Review,O=" + domainOf(hostname);

    final File tmpdir = new File(site.etc_dir, "tmp.sslcertgen");
    if (!tmpdir.mkdir()) {
      throw die("Cannot create directory " + tmpdir);
    }
    chmod(0600, tmpdir);

    final File tmpstore = new File(tmpdir, "keystore");
    Runtime.getRuntime().exec(new String[] {"keytool", //
        "-keystore", tmpstore.getAbsolutePath(), //
        "-storepass", ssl_pass, //
        "-genkeypair", //
        "-alias", hostname, //
        "-keyalg", "RSA", //
        "-validity", validity, //
        "-dname", dname, //
        "-keypass", ssl_pass, //
    }).waitFor();
    chmod(0600, tmpstore);

    if (!tmpstore.renameTo(store)) {
      throw die("Cannot rename " + tmpstore + " to " + store);
    }
    if (!tmpdir.delete()) {
      throw die("Cannot delete " + tmpdir);
    }
  }

  @Override
  public void postRun() throws Exception {
  }
}
