// Copyright (C) 2014 Google Inc. All Rights Reserved.
//
// 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.gitiles.blame;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gitiles.BaseServlet;
import com.google.gitiles.BlobSoyData;
import com.google.gitiles.CommitSoyData;
import com.google.gitiles.DateFormatter;
import com.google.gitiles.DateFormatter.Format;
import com.google.gitiles.GitilesAccess;
import com.google.gitiles.GitilesRequestFailureException;
import com.google.gitiles.GitilesRequestFailureException.FailureReason;
import com.google.gitiles.GitilesView;
import com.google.gitiles.Renderer;
import com.google.gitiles.ViewFilter;
import com.google.gitiles.blame.cache.BlameCache;
import com.google.gitiles.blame.cache.Region;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Serves an HTML page with blame data for a commit. */
public class BlameServlet extends BaseServlet {
  private static final long serialVersionUID = 1L;
  private static final Logger log = LoggerFactory.getLogger(BlameServlet.class);

  private final BlameCache cache;

  public BlameServlet(GitilesAccess.Factory accessFactory, Renderer renderer, BlameCache cache) {
    super(renderer, accessFactory);
    this.cache = checkNotNull(cache, "cache");
  }

  @Override
  protected void doGetHtml(HttpServletRequest req, HttpServletResponse res) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    Repository repo = ServletUtils.getRepository(req);

    try (RevWalk rw = new RevWalk(repo)) {
      GitilesAccess access = getAccess(req);
      RegionResult result = getRegions(view, access, repo, rw);
      if (result == null) {
        return;
      }

      String title = "Blame - " + view.getPathPart();
      Map<String, ?> blobData =
          new BlobSoyData(rw.getObjectReader(), view).toSoyData(view.getPathPart(), result.blobId);
      if (blobData.get("lines") != null) {
        DateFormatter df = new DateFormatter(access, Format.ISO);
        renderHtml(
            req,
            res,
            "com.google.gitiles.templates.BlameDetail.blameDetail",
            ImmutableMap.of(
                "title",
                title,
                "breadcrumbs",
                view.getBreadcrumbs(),
                "data",
                blobData,
                "regions",
                toSoyData(view, rw.getObjectReader(), result.regions, df)));
      } else {
        renderHtml(
            req,
            res,
            "com.google.gitiles.templates.BlameDetail.blameDetail",
            ImmutableMap.of(
                "title", title,
                "breadcrumbs", view.getBreadcrumbs(),
                "data", blobData));
      }
    }
  }

  @Override
  protected void doGetJson(HttpServletRequest req, HttpServletResponse res) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    Repository repo = ServletUtils.getRepository(req);

    try (RevWalk rw = new RevWalk(repo)) {
      RegionResult result = getRegions(view, getAccess(req), repo, rw);
      if (result == null) {
        return;
      }
      // Output from BlameCache is 0-based for lines. We convert to 1-based for
      // JSON output later (in RegionAdapter); here we're just filling in the
      // transient fields.
      int start = 0;
      for (Region r : result.regions) {
        r.setStart(start);
        start += r.getCount();
      }
      renderJson(
          req,
          res,
          ImmutableMap.of("regions", result.regions),
          new TypeToken<Map<String, List<Region>>>() {}.getType());
    }
  }

  @Override
  protected GsonBuilder newGsonBuilder(HttpServletRequest req) throws IOException {
    return super.newGsonBuilder(req)
        .registerTypeAdapter(
            Region.class, new RegionAdapter(new DateFormatter(getAccess(req), Format.ISO)));
  }

  private static class RegionResult {
    private final List<Region> regions;
    private final ObjectId blobId;

    private RegionResult(List<Region> regions, ObjectId blobId) {
      this.regions = regions;
      this.blobId = blobId;
    }
  }

  private RegionResult getRegions(
      GitilesView view, GitilesAccess access, Repository repo, RevWalk rw) throws IOException {
    RevCommit currCommit = rw.parseCommit(view.getRevision().getId());
    ObjectId currCommitBlobId = resolveBlob(view, rw, currCommit);
    if (currCommitBlobId == null) {
      throw new GitilesRequestFailureException(FailureReason.OBJECT_NOT_FOUND);
    }

    ObjectId lastCommit = cache.findLastCommit(repo, currCommit, view.getPathPart());
    ObjectId lastCommitBlobId = resolveBlob(view, rw, lastCommit);

    if (!Objects.equals(currCommitBlobId, lastCommitBlobId)) {
      log.warn(
          "Blob {} in last modified commit {} for repo {} starting from {}"
              + " does not match original blob {}",
          ObjectId.toString(lastCommitBlobId),
          ObjectId.toString(lastCommit),
          access.getRepositoryName(),
          ObjectId.toString(currCommit),
          ObjectId.toString(currCommitBlobId));
      lastCommitBlobId = currCommitBlobId;
      lastCommit = currCommit;
    }

    List<Region> regions = cache.get(repo, lastCommit, view.getPathPart());
    if (regions.isEmpty()) {
      throw new GitilesRequestFailureException(FailureReason.BLAME_REGION_NOT_FOUND);
    }
    return new RegionResult(regions, lastCommitBlobId);
  }

  private static @Nullable ObjectId resolveBlob(GitilesView view, RevWalk rw, ObjectId commitId)
      throws IOException {
    try {
      if (commitId == null || Strings.isNullOrEmpty(view.getPathPart())) {
        return null;
      }
      RevTree tree = rw.parseTree(commitId);
      TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), view.getPathPart(), tree);
      if (tw == null || (tw.getRawMode(0) & FileMode.TYPE_MASK) != FileMode.TYPE_FILE) {
        return null;
      }
      return tw.getObjectId(0);
    } catch (IncorrectObjectTypeException e) {
      return null;
    }
  }

  private static final ImmutableList<String> CLASSES =
      ImmutableList.of("Blame-region--bg1", "Blame-region--bg2");
  private static final ImmutableList<ImmutableMap<String, Object>> NULLS;

  static {
    ImmutableList.Builder<ImmutableMap<String, Object>> nulls = ImmutableList.builder();
    for (String clazz : CLASSES) {
      nulls.add(ImmutableMap.of("class", clazz));
    }
    NULLS = nulls.build();
  }

  private static List<ImmutableMap<String, Object>> toSoyData(
      GitilesView view, ObjectReader reader, List<Region> regions, DateFormatter df)
      throws IOException {
    Map<ObjectId, String> abbrevShas = Maps.newHashMap();
    ImmutableList.Builder<ImmutableMap<String, Object>> result = ImmutableList.builder();

    for (int i = 0; i < regions.size(); i++) {
      Region r = regions.get(i);
      int c = i % CLASSES.size();
      if (r.getSourceCommit() == null) {
        // JGit bug may fail to blame some regions. We should fix this
        // upstream, but handle it for now.
        result.add(NULLS.get(c));
      } else {
        String abbrevSha = abbrevShas.get(r.getSourceCommit());
        if (abbrevSha == null) {
          abbrevSha = reader.abbreviate(r.getSourceCommit()).name();
          abbrevShas.put(r.getSourceCommit(), abbrevSha);
        }
        ImmutableMap.Builder<String, Object> e = ImmutableMap.builder();
        e.put("abbrevSha", abbrevSha);
        String blameParent = "";
        String blameText = "blame";
        if (view.getRevision().getName().equals(r.getSourceCommit().name())) {
          blameParent = "^";
          blameText = "blame^";
        }
        e.put(
            "blameUrl",
            GitilesView.blame()
                .copyFrom(view)
                .setRevision(r.getSourceCommit().name() + blameParent)
                .setPathPart(r.getSourcePath())
                .toUrl());
        e.put("blameText", blameText);
        e.put(
            "commitUrl",
            GitilesView.revision().copyFrom(view).setRevision(r.getSourceCommit().name()).toUrl());
        e.put(
            "diffUrl",
            GitilesView.diff()
                .copyFrom(view)
                .setRevision(r.getSourceCommit().name())
                .setPathPart(r.getSourcePath())
                .toUrl());
        e.put("author", CommitSoyData.toSoyData(r.getSourceAuthor(), df));
        e.put("class", CLASSES.get(c));
        result.add(e.build());
      }
      // Pad the list with null regions so we can iterate in parallel in the
      // template. We can't do this by maintaining an index variable into the
      // regions list because Soy {let} is an unmodifiable alias scoped to a
      // single block.
      for (int j = 0; j < r.getCount() - 1; j++) {
        result.add(NULLS.get(c));
      }
    }
    return result.build();
  }
}
