// 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.google.gitiles;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.toList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefDatabase;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
import org.eclipse.jgit.util.io.NullOutputStream;

/** Format-independent data about a single commit. */
class CommitData {
  enum Field {
    ABBREV_SHA,
    ARCHIVE_TYPE,
    ARCHIVE_URL,
    AUTHOR,
    BRANCHES,
    COMMITTER,
    DIFF_TREE,
    LOG_URL,
    MESSAGE,
    NOTES,
    PARENTS,
    PARENT_BLAME_URL,
    SHA,
    SHORT_MESSAGE,
    TAGS,
    TREE,
    TREE_URL,
    URL;

    static ImmutableSet<Field> setOf(Iterable<Field> base, Field... fields) {
      return Sets.immutableEnumSet(Iterables.concat(base, Arrays.asList(fields)));
    }
  }

  static class DiffList {
    Revision revision;
    Revision oldRevision;
    List<DiffEntry> entries;
  }

  static class Builder {
    private ArchiveFormat archiveFormat;
    private Map<String, Map<AnyObjectId, List<Ref>>> refsByIdByPrefix;
    private static final int MAX_NOTE_SIZE = 524288;

    Builder setArchiveFormat(@Nullable ArchiveFormat archiveFormat) {
      this.archiveFormat = archiveFormat;
      return this;
    }

    CommitData build(HttpServletRequest req, RevWalk walk, RevCommit c, Set<Field> fs)
        throws IOException {
      checkFields(fs);
      checkNotNull(req, "request");
      checkNotNull(walk, "walk");
      Repository repo = ServletUtils.getRepository(req);
      GitilesView view = ViewFilter.getView(req);

      CommitData result = new CommitData();

      if (fs.contains(Field.AUTHOR)) {
        walk.parseBody(c);
        result.author = c.getAuthorIdent();
      }
      if (fs.contains(Field.COMMITTER)) {
        walk.parseBody(c);
        result.committer = c.getCommitterIdent();
      }
      if (fs.contains(Field.SHA)) {
        result.sha = c.copy();
      }
      if (fs.contains(Field.ABBREV_SHA)) {
        try (ObjectReader reader = repo.getObjectDatabase().newReader()) {
          result.abbrev = reader.abbreviate(c);
        }
      }
      if (fs.contains(Field.URL)) {
        result.url = GitilesView.revision().copyFrom(view).setRevision(c).toUrl();
      }
      if (fs.contains(Field.LOG_URL)) {
        result.logUrl = urlFromView(view, c, GitilesView.log());
      }
      if (fs.contains(Field.ARCHIVE_URL)) {
        result.archiveUrl =
            urlFromView(
                view, c, GitilesView.archive().setExtension(archiveFormat.getDefaultSuffix()));
      }
      if (fs.contains(Field.ARCHIVE_TYPE)) {
        result.archiveType = archiveFormat;
      }
      if (fs.contains(Field.TREE)) {
        result.tree = c.getTree().copy();
      }
      if (fs.contains(Field.TREE_URL)) {
        // Tree always implies the root tree.
        result.treeUrl = GitilesView.path().copyFrom(view).setPathPart("/").toUrl();
      }
      if (fs.contains(Field.PARENTS)) {
        result.parents = Arrays.asList(c.getParents());
      }
      if (fs.contains(Field.BRANCHES)) {
        result.branches = getRefsById(repo, c, Constants.R_HEADS);
      }
      if (fs.contains(Field.TAGS)) {
        result.tags = getRefsById(repo, c, Constants.R_TAGS);
      }
      if (fs.contains(Field.NOTES)) {
        Ref notesRef = repo.getRefDatabase().exactRef(Constants.R_NOTES_COMMITS);
        if (notesRef != null) {
          try {
            byte[] data =
                NoteMap.read(walk.getObjectReader(), walk.parseCommit(notesRef.getObjectId()))
                    .getCachedBytes(c, MAX_NOTE_SIZE);
            result.notes = new String(data, UTF_8);
          } catch (Exception e) {
            result.notes = "";
          }
        }
      }
      if (fs.contains(Field.MESSAGE)) {
        walk.parseBody(c);
        result.message = c.getFullMessage();
      }
      if (fs.contains(Field.SHORT_MESSAGE)) {
        walk.parseBody(c);
        String msg = c.getShortMessage();
        if (msg.length() > 80) {
          String ft = result.message;
          if (ft == null) {
            ft = c.getFullMessage();
          }
          int lf = ft.indexOf('\n');
          if (lf > 0) {
            msg = ft.substring(0, lf);
          }
        }
        result.shortMessage = msg;
      }
      if (fs.contains(Field.DIFF_TREE)) {
        result.diffEntries = computeDiffEntries(repo, view, walk, c);
      }
      return result;
    }

    private void checkFields(Set<Field> fs) {
      if (fs.contains(Field.ARCHIVE_URL) || fs.contains(Field.ARCHIVE_TYPE)) {
        checkState(archiveFormat != null, "archive format required");
      }
    }

    private static String urlFromView(
        GitilesView view, RevCommit commit, GitilesView.Builder builder) {
      Revision rev = view.getRevision();
      return builder
          .copyFrom(view)
          .setOldRevision(Revision.NULL)
          .setRevision(rev.getId().equals(commit) ? rev.getName() : commit.name(), commit)
          .setPathPart(view.getPathPart())
          .toUrl();
    }

    private List<Ref> getRefsById(Repository repo, ObjectId id, String prefix) throws IOException {
      if (refsByIdByPrefix == null) {
        refsByIdByPrefix = new HashMap<>();
      }
      Map<AnyObjectId, List<Ref>> refsById = refsByIdByPrefix.get(prefix);
      if (refsById == null) {
        // Index only refs under this namespace. getAllRefsByPeeledObjectId peels every ref, which
        // is catastrophic on repos with many refs (e.g. Gerrit's refs/changes/*).
        Map<AnyObjectId, Set<Ref>> unsortedRefsById = new HashMap<>();
        RefDatabase refDb = repo.getRefDatabase();
        for (Ref ref : refDb.getRefsByPrefix(prefix)) {
          ObjectId target;
          try {
            target = refDb.peel(ref).getPeeledObjectId();
          } catch (IOException e) {
            // Treat an unpeelable ref (e.g. missing target) as unpeeled rather than failing the
            // whole page, like Repository#peel.
            target = null;
          }
          if (target == null) {
            target = ref.getObjectId();
          }
          if (target != null) {
            unsortedRefsById.computeIfAbsent(target, k -> new HashSet<>()).add(ref);
          }
        }
        refsById = new HashMap<>();
        for (Map.Entry<AnyObjectId, Set<Ref>> e : unsortedRefsById.entrySet()) {
          refsById.put(
              e.getKey(), e.getValue().stream().sorted(comparing(Ref::getName)).collect(toList()));
        }
        refsByIdByPrefix.put(prefix, refsById);
      }
      return refsById.getOrDefault(id, ImmutableList.of());
    }

    private AbstractTreeIterator getTreeIterator(RevWalk walk, RevCommit commit)
        throws IOException {
      CanonicalTreeParser p = new CanonicalTreeParser();
      p.reset(walk.getObjectReader(), walk.parseTree(walk.parseCommit(commit).getTree()));
      return p;
    }

    private DiffList computeDiffEntries(
        Repository repo, GitilesView view, RevWalk walk, RevCommit commit) throws IOException {
      DiffList result = new DiffList();
      result.revision =
          view.getRevision().matches(commit)
              ? view.getRevision()
              : Revision.peeled(commit.name(), commit);

      AbstractTreeIterator oldTree;
      switch (commit.getParentCount()) {
        case 0:
          result.oldRevision = Revision.NULL;
          oldTree = new EmptyTreeIterator();
          break;
        case 1:
          result.oldRevision =
              Revision.peeled(result.revision.getName() + "^", commit.getParent(0));
          oldTree = getTreeIterator(walk, commit.getParent(0));
          break;
        default:
          // TODO(dborowitz): handle merges
          return result;
      }
      AbstractTreeIterator newTree = getTreeIterator(walk, commit);

      try (DiffFormatter diff = new DiffFormatter(NullOutputStream.INSTANCE)) {
        diff.setRepository(repo);
        diff.setDetectRenames(true);
        result.entries = diff.scan(oldTree, newTree);
        return result;
      }
    }
  }

  ObjectId sha;
  PersonIdent author;
  PersonIdent committer;
  AbbreviatedObjectId abbrev;
  ObjectId tree;
  List<RevCommit> parents;
  String shortMessage;
  String message;
  String notes;

  List<Ref> branches;
  List<Ref> tags;
  DiffList diffEntries;

  String url;
  String logUrl;
  String treeUrl;
  String archiveUrl;
  ArchiveFormat archiveType;
}
