// Copyright (C) 2016 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.gerrit.server.mail.send;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.server.util.AttentionSetUtil.additionsOnly;

import com.google.auto.factory.AutoFactory;
import com.google.auto.factory.Provided;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Address;
import com.google.gerrit.entities.AttentionSetUpdate;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.ChangeSizeBucket;
import com.google.gerrit.entities.NotifyConfig.NotifyType;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.PatchSetInfo;
import com.google.gerrit.entities.Project;
import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.RecipientType;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.mail.MailHeader;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.mail.send.ProjectWatch.Watchers;
import com.google.gerrit.server.mail.send.ProjectWatch.Watchers.WatcherList;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.patch.DiffNotAvailableException;
import com.google.gerrit.server.patch.DiffOptions;
import com.google.gerrit.server.patch.FilePathAdapter;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.patch.filediff.FileDiffOutput;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData;
import java.io.IOException;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
import org.apache.james.mime4j.dom.field.FieldName;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.TemporaryBuffer;

/** Populates an email for change related notifications. */
@AutoFactory
public class ChangeEmailImpl implements ChangeEmail {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  // Available after construction
  protected final EmailArguments args;
  protected final Set<Account.Id> currentAttentionSet;
  protected final Change change;
  protected final ChangeData changeData;
  protected final BranchNameKey branch;
  protected final ChangeEmailDecorator changeEmailDecorator;

  // Available after init or after being explicitly set.
  protected OutgoingEmail email;
  private ImmutableList<Account.Id> stars;
  protected PatchSet patchSet;
  protected PatchSetInfo patchSetInfo;
  private String changeMessage;
  private String changeMessageThreadId;
  private Instant timestamp;
  private ProjectState projectState;
  private Set<Account.Id> authors;
  private boolean emailOnlyAuthors;
  private boolean emailOnlyAttentionSetIfEnabled;
  // Watchers ignore attention set rules.
  private Set<Account.Id> watcherAccounts = new HashSet<>();
  // Watcher can only be an email if it's specified in notify section of ProjectConfig.
  private Set<Address> watcherEmails = new HashSet<>();
  private boolean isThreadReply = false;

  public ChangeEmailImpl(
      @Provided EmailArguments args,
      Project.NameKey project,
      Change.Id changeId,
      ChangeEmailDecorator changeEmailDecorator) {
    this.args = args;
    this.changeData = args.newChangeData(project, changeId);
    change = changeData.change();
    emailOnlyAuthors = false;
    emailOnlyAttentionSetIfEnabled = true;
    currentAttentionSet = getAttentionSet();
    branch = changeData.change().getDest();
    this.changeEmailDecorator = changeEmailDecorator;
  }

  @Override
  public void markAsReply() {
    isThreadReply = true;
  }

  @Override
  public Change getChange() {
    return change;
  }

  @Override
  public ChangeData getChangeData() {
    return changeData;
  }

  @Override
  @Nullable
  public Instant getTimestamp() {
    return timestamp;
  }

  @Override
  public void setPatchSet(PatchSet ps) {
    patchSet = ps;
  }

  @Override
  @Nullable
  public PatchSet getPatchSet() {
    return patchSet;
  }

  @Override
  public void setPatchSet(PatchSet ps, PatchSetInfo psi) {
    patchSet = ps;
    patchSetInfo = psi;
  }

  @Override
  public void setChangeMessage(String cm, Instant t) {
    changeMessage = cm;
    timestamp = t;
  }

  @Override
  public void setEmailOnlyAttentionSetIfEnabled(boolean value) {
    emailOnlyAttentionSetIfEnabled = value;
  }

  @Override
  public boolean shouldSendMessage() {
    return changeEmailDecorator.shouldSendMessage();
  }

  @Override
  public void init(OutgoingEmail email) throws EmailException {
    this.email = email;

    changeMessageThreadId =
        String.format(
            "<gerrit.%s.%s@%s>",
            change.getCreatedOn().toEpochMilli(), change.getKey().get(), email.getGerritHost());

    if (email.getFrom() != null) {
      // Is the from user in an email squelching group?
      try {
        args.permissionBackend.absentUser(email.getFrom()).check(GlobalPermission.EMAIL_REVIEWERS);
      } catch (AuthException | PermissionBackendException e) {
        emailOnlyAuthors = true;
      }
    }

    if (args.projectCache != null) {
      projectState = args.projectCache.get(change.getProject()).orElse(null);
    } else {
      projectState = null;
    }

    if (patchSet == null) {
      try {
        patchSet = changeData.currentPatchSet();
      } catch (StorageException err) {
        patchSet = null;
      }
    }

    if (patchSet != null) {
      email.setHeader(MailHeader.PATCH_SET.fieldName(), patchSet.number() + "");
      if (patchSetInfo == null) {
        try {
          patchSetInfo = args.patchSetInfoFactory.get(changeData.notes(), patchSet.id());
        } catch (PatchSetInfoNotAvailableException | StorageException err) {
          patchSetInfo = null;
        }
      }
    }

    try {
      stars = changeData.stars();
    } catch (StorageException e) {
      throw new EmailException("Failed to load stars for change " + change.getChangeId(), e);
    }

    BranchEmailUtils.setListIdHeader(email, branch);
    if (timestamp != null) {
      email.setHeader(FieldName.DATE, timestamp);
    }
    email.setHeader(MailHeader.CHANGE_ID.fieldName(), "" + change.getKey().get());
    email.setHeader(MailHeader.CHANGE_NUMBER.fieldName(), "" + change.getChangeId());
    email.setHeader(MailHeader.PROJECT.fieldName(), "" + change.getProject());
    setChangeUrlHeader();
    setCommitIdHeader();

    changeEmailDecorator.init(email, this);
  }

  private void setChangeUrlHeader() {
    final String u = getChangeUrl();
    if (u != null) {
      email.setHeader(MailHeader.CHANGE_URL.fieldName(), "<" + u + ">");
    }
  }

  private void setCommitIdHeader() {
    if (patchSet != null) {
      email.setHeader(MailHeader.COMMIT.fieldName(), patchSet.commitId().name());
    }
  }

  protected void setChangeSubjectHeader() {
    email.setHeader(FieldName.SUBJECT, email.textTemplate("ChangeSubject"));
  }

  @Override
  public int getInsertionsCount() {
    return listModifiedFiles().entrySet().stream()
        .filter(e -> !Patch.COMMIT_MSG.equals(e.getKey()))
        .map(Map.Entry::getValue)
        .map(FileDiffOutput::insertions)
        .reduce(0, Integer::sum);
  }

  @Override
  public int getDeletionsCount() {
    return listModifiedFiles().values().stream()
        .map(FileDiffOutput::deletions)
        .reduce(0, Integer::sum);
  }

  /**
   * Get a link to the change; null if the server doesn't know its own address or if the address is
   * malformed. The link will contain a usp parameter set to "email" to inform the frontend on
   * clickthroughs where the link came from.
   */
  @Nullable
  protected String getChangeUrl() {
    return args.urlFormatter
        .get()
        .getChangeViewUrl(change.getProject(), change.getId())
        .map(EmailArguments::addUspParam)
        .orElse(null);
  }

  /** Sets headers for conversation grouping */
  protected void setThreadHeaders() {
    if (isThreadReply) {
      email.setHeader("In-Reply-To", changeMessageThreadId);
    }
    email.setHeader("References", changeMessageThreadId);
  }

  /** Get the text of the "cover letter". */
  @Override
  public String getCoverLetter() {
    if (changeMessage != null) {
      return changeMessage.trim();
    }
    return "";
  }

  /** Create the change message and the affected file list. */
  protected String getChangeDetail() {
    try {
      StringBuilder detail = new StringBuilder();

      if (patchSetInfo != null) {
        detail.append(patchSetInfo.getMessage().trim()).append("\n");
      } else {
        detail.append(change.getSubject().trim()).append("\n");
      }

      if (patchSet != null) {
        detail.append("---\n");
        // Sort files by name.
        TreeMap<String, FileDiffOutput> modifiedFiles = new TreeMap<>(listModifiedFiles());
        for (FileDiffOutput fileDiff : modifiedFiles.values()) {
          if (fileDiff.newPath().isPresent() && Patch.isMagic(fileDiff.newPath().get())) {
            continue;
          }
          detail
              .append(fileDiff.changeType().getCode())
              .append(" ")
              .append(
                  FilePathAdapter.getNewPath(
                      fileDiff.oldPath(), fileDiff.newPath(), fileDiff.changeType()))
              .append("\n");
        }
        detail.append(
            MessageFormat.format(
                "" //
                    + "{0,choice,0#0 files|1#1 file|1<{0} files} changed, " //
                    + "{1,choice,0#0 insertions|1#1 insertion|1<{1} insertions}(+), " //
                    + "{2,choice,0#0 deletions|1#1 deletion|1<{2} deletions}(-)" //
                    + "\n",
                modifiedFiles.size() - 1, // -1 to account for the commit message
                getInsertionsCount(),
                getDeletionsCount()));
        detail.append("\n");
      }
      return detail.toString();
    } catch (Exception err) {
      logger.atWarning().withCause(err).log("Cannot format change detail");
      return "";
    }
  }

  /** Get the patch list corresponding to patch set patchSetId of this change. */
  @Override
  public Map<String, FileDiffOutput> listModifiedFiles(int patchSetId) {
    try {
      PatchSet ps;
      if (patchSetId == patchSet.number()) {
        ps = patchSet;
      } else {
        ps = args.patchSetUtil.get(changeData.notes(), PatchSet.id(change.getId(), patchSetId));
      }
      return args.diffOperations.listModifiedFilesAgainstParent(
          change.getProject(), ps.commitId(), /* parentNum= */ 0, DiffOptions.DEFAULTS);
    } catch (StorageException | DiffNotAvailableException e) {
      logger.atSevere().withCause(e).log("Failed to get modified files");
      return new HashMap<>();
    }
  }

  /** Get the patch list corresponding to this patch set. */
  @Override
  public Map<String, FileDiffOutput> listModifiedFiles() {
    if (patchSet != null) {
      try {
        return args.diffOperations.listModifiedFilesAgainstParent(
            change.getProject(), patchSet.commitId(), /* parentNum= */ 0, DiffOptions.DEFAULTS);
      } catch (DiffNotAvailableException e) {
        logger.atSevere().withCause(e).log("Failed to get modified files");
      }
    } else {
      logger.atSevere().log("no patchSet specified");
    }
    return new HashMap<>();
  }

  /** Get the project entity the change is in; null if its been deleted. */
  @Override
  public ProjectState getProjectState() {
    return projectState;
  }

  /** TO or CC all vested parties (change owner, patch set uploader, author). */
  @Override
  public void addAuthors(RecipientType rt) {
    for (Account.Id id : getAuthors()) {
      email.addByAccountId(rt, id);
    }
  }

  /** BCC any user who has starred this change. */
  @Override
  public void bccStarredBy() {
    if (!NotifyHandling.ALL.equals(email.getNotify().handling())) {
      return;
    }

    stars.forEach(accountId -> email.addByAccountId(RecipientType.BCC, accountId));
  }

  /** Include users and groups that want notification of events. */
  @Override
  public void includeWatchers(NotifyType type) {
    includeWatchers(type, true);
  }

  /** Include users and groups that want notification of events. */
  @Override
  public void includeWatchers(NotifyType type, boolean includeWatchersFromNotifyConfig) {
    try {
      Watchers matching = getWatchers(type, includeWatchersFromNotifyConfig);
      addWatchers(RecipientType.TO, matching.to);
      addWatchers(RecipientType.CC, matching.cc);
      addWatchers(RecipientType.BCC, matching.bcc);
    } catch (StorageException err) {
      // Just don't CC everyone. Better to send a partial message to those
      // we already have queued up then to fail deliver entirely to people
      // who have a lower interest in the change.
      logger.atWarning().withCause(err).log("Cannot BCC watchers for %s", type);
    }
  }

  /** Add users or email addresses to the TO, CC, or BCC list. */
  private void addWatchers(RecipientType type, WatcherList watcherList) {
    watcherAccounts.addAll(watcherList.accounts);
    for (Account.Id user : watcherList.accounts) {
      email.addByAccountId(type, user);
    }

    watcherEmails.addAll(watcherList.emails);
    for (Address addr : watcherList.emails) {
      email.addByEmail(type, addr);
    }
  }

  private final Watchers getWatchers(NotifyType type, boolean includeWatchersFromNotifyConfig) {
    if (!NotifyHandling.ALL.equals(email.getNotify().handling())) {
      return new Watchers();
    }

    ProjectWatch watch = new ProjectWatch(args, branch.project(), projectState, changeData);
    return watch.getWatchers(type, includeWatchersFromNotifyConfig);
  }

  /** CC all users who are added as reviewer or cc to the change. */
  @Override
  public void ccAllApprovals() {
    if (!NotifyHandling.ALL.equals(email.getNotify().handling())
        && !NotifyHandling.OWNER_REVIEWERS.equals(email.getNotify().handling())) {
      return;
    }

    try {
      for (Account.Id id : changeData.reviewers().all()) {
        email.addByAccountId(RecipientType.CC, id);
      }
      for (Address addr : this.changeData.reviewersByEmail().all()) {
        email.addByEmail(RecipientType.CC, addr);
      }
    } catch (StorageException err) {
      logger.atWarning().withCause(err).log("Cannot CC users that reviewed updated change");
    }
  }

  /** Users who were added as reviewers to this change. */
  @Override
  public void ccExistingReviewers() {
    if (!NotifyHandling.ALL.equals(email.getNotify().handling())
        && !NotifyHandling.OWNER_REVIEWERS.equals(email.getNotify().handling())) {
      return;
    }

    try {
      for (Account.Id id : changeData.reviewers().byState(ReviewerStateInternal.REVIEWER)) {
        email.addByAccountId(RecipientType.CC, id);
      }
      for (Address addr : changeData.reviewersByEmail().byState(ReviewerStateInternal.REVIEWER)) {
        email.addByEmail(RecipientType.CC, addr);
      }
    } catch (StorageException err) {
      logger.atWarning().withCause(err).log("Cannot CC users that commented on updated change");
    }
  }

  @Override
  public boolean isRecipientAllowed(Address addr) throws PermissionBackendException {
    if (!projectState.statePermitsRead()) {
      return false;
    }
    if (emailOnlyAuthors) {
      return false;
    }

    // If the email is a watcher email, skip permission check. An email can only be a watcher if
    // it is specified in notify section of ProjectConfig, so we trust that the recipient is
    // allowed.
    if (watcherEmails.contains(addr)) {
      return true;
    }
    return args.permissionBackend
        .user(args.anonymousUser.get())
        .change(changeData)
        .test(ChangePermission.READ);
  }

  @Override
  public boolean isRecipientAllowed(Account.Id to) throws PermissionBackendException {
    if (!projectState.statePermitsRead()) {
      return false;
    }
    if (emailOnlyAuthors && !getAuthors().contains(to)) {
      return false;
    }
    // Watchers ignore AttentionSet rules.
    if (!watcherAccounts.contains(to)) {
      Optional<AccountState> accountState = args.accountCache.get(to);
      if (emailOnlyAttentionSetIfEnabled
          && accountState.isPresent()
          && accountState.get().generalPreferences().getEmailStrategy()
              == EmailStrategy.ATTENTION_SET_ONLY
          && !currentAttentionSet.contains(to)) {
        return false;
      }
    }
    return args.permissionBackend.absentUser(to).change(changeData).test(ChangePermission.READ);
  }

  /** Lazily finds all users who are authors of any part of this change. */
  private Set<Account.Id> getAuthors() {
    if (this.authors != null) {
      return this.authors;
    }
    Set<Account.Id> authors = new HashSet<>();

    switch (email.getNotify().handling()) {
      case NONE:
        break;
      case ALL:
      default:
        if (patchSet != null) {
          authors.add(patchSet.uploader());
        }
        if (patchSetInfo != null) {
          if (patchSetInfo.getAuthor().getAccount() != null) {
            authors.add(patchSetInfo.getAuthor().getAccount());
          }
          if (patchSetInfo.getCommitter().getAccount() != null) {
            authors.add(patchSetInfo.getCommitter().getAccount());
          }
        }
        // $FALL-THROUGH$
      case OWNER_REVIEWERS:
      case OWNER:
        authors.add(change.getOwner());
        break;
    }

    return this.authors = authors;
  }

  @Override
  public void populateEmailContent() throws EmailException {
    BranchEmailUtils.addBranchData(email, args, branch);
    setThreadHeaders();

    email.addSoyParam("changeId", change.getKey().get());
    email.addSoyParam("coverLetter", getCoverLetter());
    email.addSoyParam("fromName", email.getNameFor(email.getFrom()));
    email.addSoyParam("fromEmail", email.getNameEmailFor(email.getFrom()));
    email.addSoyParam("diffLines", ChangeEmail.getDiffTemplateData(getUnifiedDiff()));

    email.addSoyEmailDataParam("unifiedDiff", getUnifiedDiff());
    email.addSoyEmailDataParam("changeDetail", getChangeDetail());
    email.addSoyEmailDataParam("changeUrl", getChangeUrl());
    email.addSoyEmailDataParam("includeDiff", getIncludeDiff());

    Map<String, String> changeData = new HashMap<>();

    String subject = change.getSubject();
    String originalSubject = change.getOriginalSubject();
    changeData.put("subject", subject);
    changeData.put("originalSubject", originalSubject);
    changeData.put("shortSubject", shortenSubject(subject));
    changeData.put("shortOriginalSubject", shortenSubject(originalSubject));

    changeData.put("ownerName", email.getNameFor(change.getOwner()));
    changeData.put("ownerEmail", email.getNameEmailFor(change.getOwner()));
    changeData.put("changeNumber", Integer.toString(change.getChangeId()));
    changeData.put(
        "sizeBucket",
        ChangeSizeBucket.getChangeSizeBucket(getInsertionsCount() + getDeletionsCount()));
    email.addSoyParam("change", changeData);

    Map<String, Object> patchSetData = new HashMap<>();
    patchSetData.put("patchSetId", patchSet.number());
    patchSetData.put("refName", patchSet.refName());
    email.addSoyParam("patchSet", patchSetData);

    Map<String, Object> patchSetInfoData = new HashMap<>();
    patchSetInfoData.put("authorName", patchSetInfo.getAuthor().getName());
    patchSetInfoData.put("authorEmail", patchSetInfo.getAuthor().getEmail());
    email.addSoyParam("patchSetInfo", patchSetInfoData);

    email.addFooter(MailHeader.CHANGE_ID.withDelimiter() + change.getKey().get());
    email.addFooter(MailHeader.CHANGE_NUMBER.withDelimiter() + change.getChangeId());
    email.addFooter(MailHeader.PATCH_SET.withDelimiter() + patchSet.number());
    email.addFooter(MailHeader.OWNER.withDelimiter() + email.getNameEmailFor(change.getOwner()));
    for (String reviewer : getEmailsByState(ReviewerStateInternal.REVIEWER)) {
      email.addFooter(MailHeader.REVIEWER.withDelimiter() + reviewer);
    }
    for (String reviewer : getEmailsByState(ReviewerStateInternal.CC)) {
      email.addFooter(MailHeader.CC.withDelimiter() + reviewer);
    }
    for (Account.Id attentionUser : currentAttentionSet) {
      email.addFooter(MailHeader.ATTENTION.withDelimiter() + email.getNameEmailFor(attentionUser));
    }
    // We need names rather than account ids / emails to make it user readable.
    email.addSoyParam(
        "attentionSet",
        currentAttentionSet.stream().map(email::getNameFor).sorted().collect(toImmutableList()));

    setChangeSubjectHeader();

    if (email.useHtml()) {
      email.appendHtml(email.soyHtmlTemplate("ChangeHeaderHtml"));
    }
    email.appendText(email.textTemplate("ChangeHeader"));
    changeEmailDecorator.populateEmailContent();
    email.appendText(email.textTemplate("ChangeFooter"));
    if (email.useHtml()) {
      email.appendHtml(email.soyHtmlTemplate("ChangeFooterHtml"));
    }
  }

  /**
   * A shortened subject is the subject limited to 72 characters, with an ellipsis if it exceeds
   * that limit.
   */
  protected static String shortenSubject(String subject) {
    if (subject.length() < 73) {
      return subject;
    }
    return subject.substring(0, 69) + "...";
  }

  protected Set<String> getEmailsByState(ReviewerStateInternal state) {
    Set<String> reviewers = new TreeSet<>();
    try {
      for (Account.Id who : changeData.reviewers().byState(state)) {
        reviewers.add(email.getNameEmailFor(who));
      }
    } catch (StorageException e) {
      logger.atWarning().withCause(e).log("Cannot get change reviewers");
    }
    return reviewers;
  }

  private Set<Account.Id> getAttentionSet() {
    Set<Account.Id> attentionSet = new TreeSet<>();
    try {
      attentionSet =
          additionsOnly(changeData.attentionSet()).stream()
              .map(AttentionSetUpdate::account)
              .collect(Collectors.toSet());
    } catch (StorageException e) {
      logger.atWarning().withCause(e).log("Cannot get change attention set");
    }
    return attentionSet;
  }

  protected boolean getIncludeDiff() {
    return args.settings.includeDiff;
  }

  private static final int HEAP_EST_SIZE = 32 * 1024;

  /** Show patch set as unified difference. */
  @Override
  public String getUnifiedDiff() {
    Map<String, FileDiffOutput> modifiedFiles;
    modifiedFiles = listModifiedFiles();
    if (modifiedFiles.isEmpty()) {
      // Octopus merges are not well supported for diff output by Gerrit.
      // Currently these always have a null oldId in the PatchList.
      return "[Empty change (potentially Octopus merge); cannot be formatted as a diff.]\n";
    }

    int maxSize = args.settings.maximumDiffSize;
    TemporaryBuffer.Heap buf = new TemporaryBuffer.Heap(Math.min(HEAP_EST_SIZE, maxSize), maxSize);
    try (DiffFormatter fmt = new DiffFormatter(buf)) {
      try (Repository git = args.server.openRepository(change.getProject())) {
        try {
          ObjectId oldId = modifiedFiles.values().iterator().next().oldCommitId();
          ObjectId newId = modifiedFiles.values().iterator().next().newCommitId();
          if (oldId.equals(ObjectId.zeroId())) {
            // DiffOperations returns ObjectId.zeroId if newCommit is a root commit, i.e. has no
            // parents.
            oldId = null;
          }
          fmt.setRepository(git);
          fmt.setDetectRenames(true);
          fmt.format(oldId, newId);
          return RawParseUtils.decode(buf.toByteArray());
        } catch (IOException e) {
          if (JGitText.get().inMemoryBufferLimitExceeded.equals(e.getMessage())) {
            return "";
          }
          logger.atSevere().withCause(e).log("Cannot format patch");
          return "";
        }
      } catch (IOException e) {
        logger.atSevere().withCause(e).log("Cannot open repository to format patch");
        return "";
      }
    }
  }
}
