// 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.api.InitUtil.die;
import static com.google.gerrit.pgm.init.api.InitUtil.domainOf;
import static com.google.gerrit.pgm.init.api.InitUtil.isAnyAddress;
import static com.google.gerrit.pgm.init.api.InitUtil.toURI;

import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.pgm.init.api.InitFlags;
import com.google.gerrit.pgm.init.api.InitStep;
import com.google.gerrit.pgm.init.api.Section;
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);
  }

  @Override
  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.get("http", null, "sslKeyPassword");
    if (ssl_pass == null || ssl_pass.isEmpty()) {
      ssl_pass = SignedToken.generateRandomKey();
      flags.sec.set("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 {
  }
}
