// 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.common.flogger.FluentLogger;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.nio.file.Path;
import org.eclipse.jgit.lib.Config;

@Singleton
public class GitwebCgiConfig {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  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 = Path.of("/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.
      //
      logger.atFine().log("Assuming gitweb at %s", pkgCgi);
      cgi = pkgCgi;

    } else {
      logger.atWarning().log("gitweb not installed (no %s found)", pkgCgi);
      cgi = null;
      resourcePaths = new String[] {};
    }

    Path css = null;
    Path js = null;
    Path logo = null;
    for (String path : resourcePaths) {
      Path dir = Path.of(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;
  }

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

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

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

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