// 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.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,
            "gitiles.blameDetail",
            ImmutableMap.of(
                "title",
                title,
                "breadcrumbs",
                view.getBreadcrumbs(),
                "data",
                blobData,
                "regions",
                toSoyData(view, rw.getObjectReader(), result.regions, df)));
      } else {
        renderHtml(
            req,
            res,
            "gitiles.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 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();
  }
}
