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

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.common.WebLinkInfo;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.FileWebLink;
import com.google.gerrit.extensions.webui.ProjectWebLink;
import com.google.gerrit.httpd.resources.Resource;
import com.google.gerrit.reviewdb.client.Project;
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.formatter.Formatters;
import com.googlesource.gerrit.plugins.xdocs.formatter.Formatters.FormatterProvider;
import java.io.IOException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Singleton
public class XDocWebLink implements ProjectWebLink, BranchWebLink, FileWebLink {
  private static final Logger log = LoggerFactory.getLogger(XDocWebLink.class);

  private static final String README = "readme";
  private static final String PREVIEW = "preview";

  private final String pluginName;
  private final GitRepositoryManager repoManager;
  private final XDocCache docCache;
  private final XDocProjectConfig.Factory cfgFactory;
  private final ProjectCache projectCache;
  private final Formatters formatters;

  @Inject
  XDocWebLink(
      @PluginName String pluginName,
      GitRepositoryManager repoManager,
      XDocCache cache,
      XDocProjectConfig.Factory cfgFactory,
      ProjectCache projectCache,
      Formatters formatters) {
    this.pluginName = pluginName;
    this.repoManager = repoManager;
    this.docCache = cache;
    this.cfgFactory = cfgFactory;
    this.projectCache = projectCache;
    this.formatters = formatters;
  }

  @Override
  public WebLinkInfo getBranchWebLink(String projectName, String branchName) {
    String url = getBranchUrl(projectName, branchName);
    return url == null ? null : new WebLinkInfo(README, getImageUrl(), url, Target.SELF);
  }

  @Override
  public WebLinkInfo getProjectWeblink(String projectName) {
    String url = getBranchUrl(projectName, Constants.HEAD);
    return url == null ? null : new WebLinkInfo(README, getImageUrl(), url, Target.SELF);
  }

  @Override
  public WebLinkInfo getFileWebLink(String projectName, String revision, String fileName) {
    String url = getFileUrl(projectName, revision, fileName, false);
    return url == null ? null : new WebLinkInfo(PREVIEW, getImageUrl(), url, Target.BLANK);
  }

  private String getBranchUrl(String projectName, String branchName) {
    ProjectState state = projectCache.get(new Project.NameKey(projectName));
    if (state == null) {
      // project not found -> no link
      return null;
    }
    return getFileUrl(projectName, branchName, cfgFactory.create(state).getIndexFile(), true);
  }

  public String getFileUrl(String projectName, String revision, String fileName, boolean framed) {
    FormatterProvider formatter = formatters.get(projectName, fileName);
    if (formatter == null) {
      return null;
    }

    Project.NameKey p = new Project.NameKey(projectName);
    try (Repository repo = repoManager.openRepository(p)) {
      ObjectId revId = repo.resolve(revision);
      if (revId == null) {
        return null;
      }
      Resource rsc = docCache.get(formatter, p, fileName, revId, null, null);
      if (rsc != Resource.NOT_FOUND) {
        StringBuilder url = new StringBuilder();
        if (framed) {
          url.append("#/x/");
        } else {
          url.append("plugins/");
        }
        url.append(pluginName);
        url.append(XDocServlet.PATH_PREFIX);
        url.append(Url.encode(projectName));
        if (revision != null && !Constants.HEAD.equals(revision)) {
          url.append("/rev/");
          url.append(Url.encode(revision));
        }
        url.append("/");
        url.append(fileName);
        return url.toString();
      } else {
        return null;
      }
    } catch (IOException e) {
      log.error("Failed to check for project documentation", e);
      return null;
    }
  }

  private String getImageUrl() {
    return "plugins/" + pluginName + "/static/readme.png";
  }
}
