// Copyright (C) 2014 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.googlesource.gerrit.plugins.xdocs.formatter;

import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_CSS_THEME;
import static com.googlesource.gerrit.plugins.xdocs.XDocGlobalConfig.KEY_INHERIT_CSS;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.apache.commons.lang.StringEscapeUtils.escapeHtml;

import com.google.common.base.Joiner;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.PluginData;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.xdocs.ConfigSection;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

  private final String pluginName;
  private final File baseDir;
  private final GitRepositoryManager repoManager;
  private final ProjectCache projectCache;
  private final Formatters formatters;
  private final Map<String, String> defaultCss;

  @Inject
  FormatterUtil(
      @PluginName String pluginName,
      @PluginData File baseDir,
      GitRepositoryManager repoManager,
      ProjectCache projectCache,
      Formatters formatters) {
    this.pluginName = pluginName;
    this.baseDir = baseDir;
    this.repoManager = repoManager;
    this.projectCache = projectCache;
    this.formatters = formatters;
    this.defaultCss = new HashMap<>();
  }

  /**
   * Returns the CSS from the file "<plugin-name>/<name>-<theme>.css" in the refs/meta/config branch
   * of the project.
   *
   * <p>If theme is <code>null</code> or empty, the CSS from the file "<plugin-name>/<name>.css" is
   * returned.
   *
   * @param name the name of the file in the "<plugin-name>/" folder without theme and without the
   *     ".css" file extension
   * @param theme the name of the CSS theme, may be <code>null</code>, if given it is included into
   *     the CSS file name: '<name>-<theme>.css'
   * @return the CSS from the file; HTML characters are escaped; <code>null</code> if the file
   *     doesn't exist
   */
  public String getCss(String projectName, String name, String theme) {
    return Strings.isNullOrEmpty(theme)
        ? getCss(projectName, name)
        : getCss(projectName, name + "-" + theme);
  }

  /**
   * Returns the CSS from the file "<plugin-name>/<name>.css" in the refs/meta/config branch of the
   * project.
   *
   * @param name the name of the file in the "<plugin-name>/" folder without the ".css" file
   *     extension
   * @return the CSS from the file; HTML characters are escaped; <code>null</code> if the file
   *     doesn't exist
   */
  public String getCss(String projectName, String name) {
    return escapeHtml(getMetaConfigFile(projectName, name + ".css"));
  }

  /**
   * Returns the inherited CSS.
   *
   * <p>If the project has a parent project the CSS of the parent project is returned; if there is
   * no parent project the global CSS is returned.
   *
   * @param projectName the name of the project
   * @param formatterName the name of the formatter for which the CSS should be returned
   * @param name the name of the CSS file without theme and without the ".css" file extension
   * @param theme the name of the CSS theme, may be <code>null</code>, if given it is included into
   *     the CSS file name: '<name>-<theme>.css'
   * @return the inherited CSS; HTML characters are escaped; <code>null</code> if there is no
   *     inherited CSS
   * @throws IOException thrown in case of an I/O Error while reading the global CSS file
   */
  public String getInheritedCss(String projectName, String formatterName, String name, String theme)
      throws IOException {
    return getInheritedCss(
        projectCache.get(new Project.NameKey(projectName)), formatterName, name, theme);
  }

  private String getInheritedCss(
      ProjectState project, String formatterName, String name, String theme) throws IOException {
    for (ProjectState parent : project.parents()) {
      String css = getCss(parent.getProject().getName(), name, theme);
      ConfigSection cfg = formatters.getFormatterConfig(formatterName, parent);
      if (cfg.getBoolean(KEY_INHERIT_CSS, true)) {
        return joinCss(getInheritedCss(parent, formatterName, name, theme), css);
      } else {
        return css;
      }
    }
    return getGlobalCss(name, theme);
  }

  private String joinCss(String css1, String css2) {
    if (css1 == null) {
      return css2;
    }
    if (css2 == null) {
      return css1;
    }
    return Joiner.on('\n').join(css1, css2);
  }

  /**
   * Returns the CSS from the file "<review-site>/data/<plugin-name>/css/<name>-<theme>.css".
   *
   * <p>If theme is <code>null</code> or empty, the CSS from the file
   * "<review-site>/data/<plugin-name>/css/<name>.css" is returned.
   *
   * @param name the name of the CSS file without theme and without the ".css" file extension
   * @param theme the name of the CSS theme, may be <code>null</code>, if given it is included into
   *     the CSS file name: '<name>-<theme>.css'
   * @return the CSS from the file; HTML characters are escaped; <code>null</code> if the file
   *     doesn't exist
   * @throws IOException thrown in case of an I/O Error while reading the CSS file
   */
  public String getGlobalCss(String name, String theme) throws IOException {
    return Strings.isNullOrEmpty(theme) ? getGlobalCss(name) : getGlobalCss(name + "-" + theme);
  }

  /**
   * Returns the CSS from the file "<review-site>/data/<plugin-name>/css/<name>.css".
   *
   * @param name the name of the CSS file without the ".css" file extension
   * @return the CSS from the file; HTML characters are escaped; <code>null</code> if the file
   *     doesn't exist
   * @throws IOException thrown in case of an I/O Error while reading the CSS file
   */
  public String getGlobalCss(String name) throws IOException {
    Path p = Paths.get(baseDir.getAbsolutePath(), "css", name + ".css");
    if (Files.exists(p)) {
      byte[] css = Files.readAllBytes(p);
      return escapeHtml(new String(css, UTF_8));
    }
    return null;
  }

  public String applyCss(String html, String formatterName, String projectName) throws IOException {
    ConfigSection projectCfg = formatters.getFormatterConfig(formatterName, projectName);
    String cssName = formatterName.toLowerCase(Locale.US);
    String cssTheme = projectCfg.getString(KEY_CSS_THEME);
    String defaultCss = getDefaultCss(formatterName);
    String inheritedCss = getInheritedCss(projectName, formatterName, cssName, cssTheme);
    String projectCss = getCss(projectName, cssName, cssTheme);
    if (projectCfg.getBoolean(KEY_INHERIT_CSS, true)) {
      return insertCss(html, MoreObjects.firstNonNull(inheritedCss, defaultCss), projectCss);
    } else {
      return insertCss(
          html,
          MoreObjects.firstNonNull(projectCss, MoreObjects.firstNonNull(inheritedCss, defaultCss)));
    }
  }

  private String getDefaultCss(String formatterName) throws IOException {
    String css = defaultCss.get(formatterName);
    if (css == null) {
      URL url = FormatterUtil.class.getResource(formatterName.toLowerCase(Locale.US) + ".css");
      if (url != null) {
        try (InputStream in = url.openStream();
            TemporaryBuffer.Heap tmp = new TemporaryBuffer.Heap(128 * 1024)) {
          tmp.copy(in);
          css = new String(tmp.toByteArray(), UTF_8);
        }
      } else {
        log.info(String.format("No default CSS for formatter '%s' found.", formatterName));
        css = "";
      }
      defaultCss.put(formatterName, css);
    }
    return css;
  }

  /**
   * Inserts the given CSS into the given HTML.
   *
   * @param html the HTML
   * @param css the CSS, may be <code>null</code>
   * @return the HTML that includes the CSS
   */
  public String insertCss(String html, String css) {
    if (html == null || css == null) {
      return html;
    }

    return insertCss(html, css, null);
  }

  /**
   * Inserts the given CSS's into the given HTML.
   *
   * @param html the HTML
   * @param css1 first CSS, may be <code>null</code>
   * @param css2 second CSS, may be <code>null</code>
   * @return the HTML that includes the CSS
   */
  public String insertCss(String html, String css1, String css2) {
    if (html == null || (css1 == null && css2 == null)) {
      return html;
    }

    int p = html.lastIndexOf("</body>");
    if (p > 0) {
      StringBuilder b = new StringBuilder();
      b.append(html.substring(0, p));
      if (css1 != null) {
        b.append("<style type=\"text/css\">\n");
        b.append(css1);
        b.append("</style>\n");
      }
      if (css2 != null) {
        b.append("<style type=\"text/css\">\n");
        b.append(css2);
        b.append("</style>\n");
      }
      b.append(html.substring(p));
      return b.toString();
    } else {
      return html;
    }
  }

  /**
   * Returns the content of the specified file from the "<plugin-name>/" folder of the
   * ref/meta/config branch.
   *
   * @param projectName the name of the project
   * @param fileName the name of the file in the "<plugin-name>/" folder
   * @return the file content, <code>null</code> if the file doesn't exist
   */
  public String getMetaConfigFile(String projectName, String fileName) {
    try (Repository repo = repoManager.openRepository(new Project.NameKey(projectName))) {
      try (RevWalk rw = new RevWalk(repo)) {
        ObjectId id = repo.resolve(RefNames.REFS_CONFIG);
        if (id == null) {
          return null;
        }
        RevCommit commit = rw.parseCommit(id);
        RevTree tree = commit.getTree();
        try (TreeWalk tw = new TreeWalk(repo)) {
          tw.addTree(tree);
          tw.setRecursive(true);
          tw.setFilter(PathFilter.create(pluginName + "/" + fileName));
          if (!tw.next()) {
            return null;
          }
          ObjectId objectId = tw.getObjectId(0);
          ObjectLoader loader = repo.open(objectId);
          byte[] raw = loader.getBytes(Integer.MAX_VALUE);
          return new String(raw, UTF_8);
        }
      }
    } catch (IOException e) {
      return null;
    }
  }
}
