// Copyright (C) 2015 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.server.config;

import static java.nio.file.Files.isExecutable;
import static java.nio.file.Files.isRegularFile;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.nio.file.Paths;

@Singleton
public class GitwebCgiConfig {
  private static final Logger log =
      LoggerFactory.getLogger(GitwebCgiConfig.class);

  public GitwebCgiConfig disabled() {
    return new GitwebCgiConfig();
  }

  private final Path cgi;
  private final Path css;
  private final Path js;
  private final Path logoPng;

  @Inject
  GitwebCgiConfig(SitePaths sitePaths, @GerritServerConfig Config cfg) {
    if (GitwebConfig.isDisabled(cfg)) {
      cgi = null;
      css = null;
      js = null;
      logoPng = null;
      return;
    }

    String cfgCgi = cfg.getString("gitweb", null, "cgi");
    Path pkgCgi = Paths.get("/usr/lib/cgi-bin/gitweb.cgi");
    String[] resourcePaths = {
        "/usr/share/gitweb/static",
        "/usr/share/gitweb",
        "/var/www/static",
        "/var/www",
    };
    Path cgi;

    if (cfgCgi != null) {
      // Use the CGI script configured by the administrator, failing if it
      // cannot be used as specified.
      //
      cgi = sitePaths.resolve(cfgCgi);
      if (!isRegularFile(cgi)) {
        throw new IllegalStateException("Cannot find gitweb.cgi: " + cgi);
      }
      if (!isExecutable(cgi)) {
        throw new IllegalStateException("Cannot execute gitweb.cgi: " + cgi);
      }

      if (!cgi.equals(pkgCgi)) {
        // Assume the administrator pointed us to the distribution,
        // which also has the corresponding CSS and logo file.
        //
        String absPath = cgi.getParent().toAbsolutePath().toString();
        resourcePaths = new String[] {absPath + "/static", absPath};
      }

    } else if (cfg.getString("gitweb", null, "url") != null) {
      // Use an externally managed gitweb instance, and not an internal one.
      //
      cgi = null;
      resourcePaths = new String[] {};

    } else if (isRegularFile(pkgCgi) && isExecutable(pkgCgi)) {
      // Use the OS packaged CGI.
      //
      log.debug("Assuming gitweb at " + pkgCgi);
      cgi = pkgCgi;

    } else {
      log.warn("gitweb not installed (no " + pkgCgi + " found)");
      cgi = null;
      resourcePaths = new String[] {};
    }

    Path css = null;
    Path js = null;
    Path logo = null;
    for (String path : resourcePaths) {
      Path dir = Paths.get(path);
      css = dir.resolve("gitweb.css");
      js = dir.resolve("gitweb.js");
      logo = dir.resolve("git-logo.png");
      if (isRegularFile(css) && isRegularFile(logo)) {
        break;
      }
    }

    this.cgi = cgi;
    this.css = css;
    this.js = js;
    this.logoPng = logo;
  }

  private GitwebCgiConfig() {
    this.cgi = null;
    this.css = null;
    this.js = null;
    this.logoPng = null;
  }

  /** @return local path to the CGI executable; null if we shouldn't execute. */
  public Path getGitwebCgi() {
    return cgi;
  }

  /** @return local path of the {@code gitweb.css} matching the CGI. */
  public Path getGitwebCss() {
    return css;
  }

  /** @return local path of the {@code gitweb.js} for the CGI. */
  public Path getGitwebJs() {
    return js;
  }

  /** @return local path of the {@code git-logo.png} for the CGI. */
  public Path getGitLogoPng() {
    return logoPng;
  }
}
