// 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.checkState;
import static org.eclipse.jgit.diff.DiffEntry.ChangeType.COPY;
import static org.eclipse.jgit.diff.DiffEntry.ChangeType.DELETE;
import static org.eclipse.jgit.diff.DiffEntry.ChangeType.RENAME;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gitiles.CommitData.DiffList;
import com.google.gitiles.CommitData.Field;
import com.google.template.soy.data.restricted.NullData;
import java.io.IOException;
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.DiffEntry.ChangeType;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.RelativeDateFormatter;

/** Soy data converter for git commits. */
public class CommitSoyData {
  static final ImmutableSet<Field> DEFAULT_FIELDS =
      Sets.immutableEnumSet(
          Field.AUTHOR,
          Field.COMMITTER,
          Field.SHA,
          Field.TREE,
          Field.TREE_URL,
          Field.PARENTS,
          Field.MESSAGE,
          Field.NOTES, // Optional Field
          Field.LOG_URL,
          Field.ARCHIVE_URL,
          Field.ARCHIVE_TYPE);

  private static final ImmutableSet<Field> NESTED_FIELDS =
      Sets.immutableEnumSet(Field.PARENT_BLAME_URL);

  private Linkifier linkifier;
  private CommitData.Builder cdb;
  private ArchiveFormat archiveFormat;

  CommitSoyData setLinkifier(@Nullable Linkifier linkifier) {
    this.linkifier = linkifier;
    return this;
  }

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

  Map<String, Object> toSoyData(
      HttpServletRequest req, RevWalk walk, RevCommit c, Set<Field> fs, DateFormatter df)
      throws IOException {
    GitilesView view = ViewFilter.getView(req);
    if (cdb == null) {
      cdb = new CommitData.Builder();
    }

    CommitData cd = cdb.setArchiveFormat(archiveFormat).build(req, walk, c, fs);

    Map<String, Object> data = Maps.newHashMapWithExpectedSize(fs.size());
    if (cd.author != null) {
      data.put("author", toSoyData(cd.author, df));
    }
    if (cd.committer != null) {
      data.put("committer", toSoyData(cd.committer, df));
    }
    if (cd.sha != null) {
      data.put("sha", cd.sha.name());
    }
    if (cd.abbrev != null) {
      data.put("abbrevSha", cd.abbrev.name());
    }
    if (cd.url != null) {
      data.put("url", cd.url);
    }
    if (cd.logUrl != null) {
      data.put("logUrl", cd.logUrl);
    }
    if (cd.archiveUrl != null) {
      data.put("archiveUrl", cd.archiveUrl);
    }
    if (cd.archiveType != null) {
      data.put("archiveType", cd.archiveType.getShortName());
    }
    if (cd.tree != null) {
      data.put("tree", cd.tree.name());
    }
    if (cd.treeUrl != null) {
      data.put("treeUrl", cd.treeUrl);
    }
    if (cd.parents != null) {
      data.put("parents", toSoyData(view, fs, cd.parents));
    }
    if (cd.shortMessage != null) {
      data.put("shortMessage", cd.shortMessage);
    }
    if (cd.branches != null) {
      data.put("branches", toSoyData(view, cd.branches, Constants.R_HEADS));
    }
    if (cd.tags != null) {
      data.put("tags", toSoyData(view, cd.tags, Constants.R_TAGS));
    }
    if (cd.message != null) {
      if (linkifier != null) {
        data.put("message", linkifier.linkify(req, cd.message));
      } else {
        data.put("message", cd.message);
      }
    }
    if (cd.diffEntries != null) {
      data.put("diffTree", toSoyData(view, cd.diffEntries));
    }

    int diffSetSize = Sets.difference(fs, NESTED_FIELDS).size();

    if (fs.contains(
        Field.NOTES)) { // Since NOTES is optional this is required for checkState to pass
      diffSetSize -= 1;
    }

    checkState(diffSetSize == data.size(), "bad commit data fields: %s != %s", fs, data.keySet());

    if (cd.notes != null && !cd.notes.isEmpty()) {
      data.put("notes", cd.notes);
    }

    return data;
  }

  Map<String, Object> toSoyData(
      HttpServletRequest req, RevWalk walk, RevCommit commit, DateFormatter df) throws IOException {
    return toSoyData(req, walk, commit, DEFAULT_FIELDS, df);
  }

  // TODO(dborowitz): Extract this.
  public static Map<String, String> toSoyData(PersonIdent ident, DateFormatter df) {
    return ImmutableMap.of(
        "name", ident.getName(),
        "email", ident.getEmailAddress(),
        "time", df.format(ident),
        // TODO(dborowitz): Switch from relative to absolute at some threshold.
        "relativeTime", RelativeDateFormatter.format(ident.getWhen()));
  }

  private List<Map<String, String>> toSoyData(
      GitilesView view, Set<Field> fs, List<RevCommit> parents) {
    List<Map<String, String>> result = Lists.newArrayListWithCapacity(parents.size());
    int i = 1;
    // TODO(dborowitz): Render something slightly different when we're actively
    // viewing a diff against one of the parents.
    for (RevCommit parent : parents) {
      String name = parent.name();
      // Clear path on parent diff view, since this parent may not have a diff
      // for the path in question.
      GitilesView.Builder diff = GitilesView.diff().copyFrom(view).setPathPart("");
      String parentName;
      if (parents.size() == 1) {
        parentName = view.getRevision().getName() + "^";
      } else {
        parentName = view.getRevision().getName() + "^" + (i++);
      }
      diff.setOldRevision(parentName, parent);

      Map<String, String> e = Maps.newHashMapWithExpectedSize(4);
      e.put("sha", name);
      e.put("url", GitilesView.revision().copyFrom(view).setRevision(parentName, parent).toUrl());
      e.put("diffUrl", diff.toUrl());
      if (fs.contains(Field.PARENT_BLAME_URL)) {
        // Assumes caller has ensured path is a file.
        e.put(
            "blameUrl",
            GitilesView.blame()
                .copyFrom(view)
                .setRevision(Revision.peeled(parentName, parent))
                .toUrl());
      }
      result.add(e);
    }
    return result;
  }

  private static Object toSoyData(GitilesView view, DiffList dl) {
    if (dl.oldRevision == null) {
      return NullData.INSTANCE;
    }
    GitilesView.Builder diffUrl =
        GitilesView.diff()
            .copyFrom(view)
            .setOldRevision(dl.oldRevision)
            .setRevision(dl.revision)
            .setPathPart("");

    List<Object> result = Lists.newArrayListWithCapacity(dl.entries.size());
    for (DiffEntry e : dl.entries) {
      Map<String, Object> entry = Maps.newHashMapWithExpectedSize(5);
      ChangeType type = e.getChangeType();
      if (type != DELETE) {
        entry.put("path", e.getNewPath());
        entry.put(
            "url",
            GitilesView.path()
                .copyFrom(view)
                .setRevision(dl.revision)
                .setPathPart(e.getNewPath())
                .toUrl());
      } else {
        entry.put("path", e.getOldPath());
        entry.put(
            "url",
            GitilesView.path()
                .copyFrom(view)
                .setRevision(dl.oldRevision)
                .setPathPart(e.getOldPath())
                .toUrl());
      }
      entry.put("diffUrl", diffUrl.setAnchor("F" + result.size()).toUrl());
      entry.put("changeType", e.getChangeType().toString());
      if (type == COPY || type == RENAME) {
        entry.put("oldPath", e.getOldPath());
      }
      result.add(entry);
    }
    return result;
  }

  private static List<Map<String, String>> toSoyData(
      GitilesView view, List<Ref> refs, String prefix) {
    List<Map<String, String>> result = Lists.newArrayListWithCapacity(refs.size());
    for (Ref ref : refs) {
      if (ref.getName().startsWith(prefix)) {
        result.add(
            ImmutableMap.of(
                "name", ref.getName().substring(prefix.length()),
                "url",
                    GitilesView.revision()
                        .copyFrom(view)
                        .setRevision(Revision.unpeeled(ref.getName(), ref.getObjectId()))
                        .toUrl()));
      }
    }
    return result;
  }
}
