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

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

import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.primitives.Longs;
import com.google.gitiles.CommitData.Field;
import com.google.gitiles.DateFormatter.Format;
import com.google.gitiles.GitilesRequestFailureException.FailureReason;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.diff.DiffConfig;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.FollowFilter;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.revwalk.filter.AndRevFilter;
import org.eclipse.jgit.revwalk.filter.RevFilter;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.StringUtils;

/** Serves an HTML page with a shortlog for commits and paths. */
public class LogServlet extends BaseServlet {
  private static final long serialVersionUID = 1L;

  static final String LIMIT_PARAM = "n";
  static final String START_PARAM = "s";

  private static final String FOLLOW_PARAM = "follow";
  private static final String NAME_STATUS_PARAM = "name-status";
  private static final String PRETTY_PARAM = "pretty";

  private static final int DEFAULT_LIMIT = 100;
  private static final int MAX_LIMIT = 10000;

  private final Linkifier linkifier;

  public LogServlet(GitilesAccess.Factory accessFactory, Renderer renderer, Linkifier linkifier) {
    super(renderer, accessFactory);
    this.linkifier = checkNotNull(linkifier, "linkifier");
  }

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

    Paginator paginator = null;
    try {
      GitilesAccess access = getAccess(req);
      paginator = newPaginator(repo, view, access);
      if (paginator == null) {
        throw new GitilesRequestFailureException(FailureReason.OBJECT_NOT_FOUND);
      }
      DateFormatter df = new DateFormatter(access, Format.DEFAULT);

      // Allow the user to select a logView variant with the "pretty" param.
      String pretty = Iterables.getFirst(view.getParameters().get(PRETTY_PARAM), "default");
      Map<String, Object> data = Maps.newHashMapWithExpectedSize(2);

      if (!view.getRevision().nameIsId()) {
        List<Map<String, Object>> tags = Lists.newArrayListWithExpectedSize(1);
        for (RevObject o : RevisionServlet.listObjects(paginator.getWalk(), view.getRevision())) {
          if (o instanceof RevTag) {
            tags.add(new TagSoyData(linkifier, req).toSoyData(paginator.getWalk(), (RevTag) o, df));
          }
        }
        if (!tags.isEmpty()) {
          data.put("tags", tags);
        }
      }

      String title = "Log - ";
      if (view.getOldRevision() != Revision.NULL) {
        title += view.getRevisionRange();
      } else {
        title += view.getRevision().getName();
      }

      data.put("title", title);

      try (OutputStream out = startRenderStreamingHtml(req, res, "gitiles.logDetail", data)) {
        Writer w = newWriter(out, res);
        new LogSoyData(req, access, pretty)
            .renderStreaming(paginator, null, renderer, w, df, LogSoyData.FooterBehavior.NEXT);
        w.flush();
      }
    } finally {
      if (paginator != null) {
        paginator.getWalk().close();
      }
    }
  }

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

    Set<Field> fs = Sets.newEnumSet(CommitJsonData.DEFAULT_FIELDS, Field.class);
    String nameStatus = Iterables.getFirst(view.getParameters().get(NAME_STATUS_PARAM), null);
    if ("1".equals(nameStatus) || "".equals(nameStatus)) {
      fs.add(Field.DIFF_TREE);
    }

    Paginator paginator = null;
    try {
      GitilesAccess access = getAccess(req);
      paginator = newPaginator(repo, view, access);
      if (paginator == null) {
        throw new GitilesRequestFailureException(FailureReason.OBJECT_NOT_FOUND);
      }
      DateFormatter df = new DateFormatter(access, Format.DEFAULT);
      CommitJsonData.Log result = new CommitJsonData.Log();
      List<CommitJsonData.Commit> entries = Lists.newArrayListWithCapacity(paginator.getLimit());
      for (RevCommit c : paginator) {
        entries.add(new CommitJsonData().toJsonData(req, paginator.getWalk(), c, fs, df));
      }
      result.log = entries;
      if (paginator.getPreviousStart() != null) {
        result.previous = paginator.getPreviousStart().name();
      }
      if (paginator.getNextStart() != null) {
        result.next = paginator.getNextStart().name();
      }
      renderJson(req, res, result, new TypeToken<CommitJsonData.Log>() {}.getType());
    } finally {
      if (paginator != null) {
        paginator.getWalk().close();
      }
    }
  }

  private static GitilesView getView(HttpServletRequest req, Repository repo) throws IOException {
    GitilesView view = ViewFilter.getView(req);
    if (view.getRevision() != Revision.NULL) {
      return view;
    }
    Ref headRef = repo.exactRef(Constants.HEAD);
    if (headRef == null) {
      return null;
    }
    try (RevWalk walk = new RevWalk(repo)) {
      return GitilesView.log()
          .copyFrom(view)
          .setRevision(Revision.peel(Constants.HEAD, walk.parseAny(headRef.getObjectId()), walk))
          .build();
    }
  }

  private static class InvalidStartValueException extends IllegalArgumentException {
    private static final long serialVersionUID = 1L;

    InvalidStartValueException() {
      super();
    }
  }

  private static Optional<ObjectId> getStart(
      ListMultimap<String, String> params, ObjectReader reader)
      throws IOException, InvalidStartValueException {
    List<String> values = params.get(START_PARAM);
    switch (values.size()) {
      case 0:
        return Optional.empty();
      case 1:
        String id = values.get(0);
        if (!AbbreviatedObjectId.isId(id)) {
          throw new InvalidStartValueException();
        }
        Collection<ObjectId> ids = reader.resolve(AbbreviatedObjectId.fromString(id));
        if (ids.size() != 1) {
          throw new InvalidStartValueException();
        }
        return Optional.of(Iterables.getOnlyElement(ids));
      default:
        throw new InvalidStartValueException();
    }
  }

  private static RevWalk newWalk(Repository repo, GitilesView view, GitilesAccess access)
      throws MissingObjectException, IOException {
    RevWalk walk = new RevWalk(repo);
    try {
      walk.markStart(walk.parseCommit(view.getRevision().getId()));
      if (view.getOldRevision() != Revision.NULL) {
        walk.markUninteresting(walk.parseCommit(view.getOldRevision().getId()));
      }
    } catch (IncorrectObjectTypeException iote) {
      return null;
    }
    setTreeFilter(walk, view, access);
    setRevFilter(walk, view);
    if (isTrue(view, "topo-order")) {
      walk.sort(RevSort.TOPO, true);
    }
    if (isTrue(view, "reverse")) {
      walk.sort(RevSort.REVERSE, true);
    }
    return walk;
  }

  private static void setRevFilter(RevWalk walk, GitilesView view) {
    List<RevFilter> filters = new ArrayList<>(3);
    if (isTrue(view, "no-merges")) {
      filters.add(RevFilter.NO_MERGES);
    }

    String author = Iterables.getFirst(view.getParameters().get("author"), null);
    if (author != null) {
      filters.add(IdentRevFilter.author(author));
    }

    String committer = Iterables.getFirst(view.getParameters().get("committer"), null);
    if (committer != null) {
      filters.add(IdentRevFilter.committer(committer));
    }

    if (filters.size() > 1) {
      walk.setRevFilter(AndRevFilter.create(filters));
    } else if (filters.size() == 1) {
      walk.setRevFilter(filters.get(0));
    }
  }

  private static void setTreeFilter(RevWalk walk, GitilesView view, GitilesAccess access)
      throws IOException {
    if (Strings.isNullOrEmpty(view.getPathPart())) {
      return;
    }
    walk.setRewriteParents(false);
    String path = view.getPathPart();

    List<String> followParams = view.getParameters().get(FOLLOW_PARAM);
    boolean follow =
        !followParams.isEmpty()
            ? isTrue(followParams.get(0))
            : access.getConfig().getBoolean("log", null, "follow", true);
    if (follow) {
      walk.setTreeFilter(FollowFilter.create(path, access.getConfig().get(DiffConfig.KEY)));
    } else {
      walk.setTreeFilter(
          AndTreeFilter.create(PathFilterGroup.createFromStrings(path), TreeFilter.ANY_DIFF));
    }
  }

  private static boolean isTrue(GitilesView view, String param) {
    return isTrue(Iterables.getFirst(view.getParameters().get(param), null));
  }

  private static boolean isTrue(String v) {
    if (v == null) {
      return false;
    } else if (v.isEmpty()) {
      return true;
    }
    return Boolean.TRUE.equals(StringUtils.toBooleanOrNull(v));
  }

  private static Paginator newPaginator(Repository repo, GitilesView view, GitilesAccess access)
      throws IOException {
    if (view == null) {
      return null;
    }

    try (RevWalk walk = newWalk(repo, view, access)) {
      if (walk == null) {
        return null;
      }

      try {
        Optional<ObjectId> start = getStart(view.getParameters(), walk.getObjectReader());
        return new Paginator(walk, getLimit(view), start.orElse(null));
      } catch (InvalidStartValueException e) {
        return null;
      }
    }
  }

  private static int getLimit(GitilesView view) {
    List<String> values = view.getParameters().get(LIMIT_PARAM);
    if (values.isEmpty()) {
      return DEFAULT_LIMIT;
    }
    Long limit = Longs.tryParse(values.get(0));
    if (limit == null) {
      return DEFAULT_LIMIT;
    }
    return (int) Math.min(limit, MAX_LIMIT);
  }
}
