// 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.gerrit.server;

import static com.google.common.collect.ImmutableSet.toImmutableSet;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.ChangeMessage;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.update.ChangeContext;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;

/** Utility functions to manipulate {@link ChangeMessage}. */
@Singleton
public class ChangeMessagesUtil {
  public static final String AUTOGENERATED_TAG_PREFIX = "autogenerated:";
  public static final String AUTOGENERATED_BY_GERRIT_TAG_PREFIX =
      AUTOGENERATED_TAG_PREFIX + "gerrit:";

  public static final String TAG_ABANDON = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "abandon";
  public static final String TAG_CHERRY_PICK_CHANGE =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "cherryPickChange";
  public static final String TAG_DELETE_ASSIGNEE =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteAssignee";
  public static final String TAG_DELETE_REVIEWER =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteReviewer";
  public static final String TAG_DELETE_VOTE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteVote";
  public static final String TAG_MERGED = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "merged";
  public static final String TAG_MOVE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "move";
  public static final String TAG_RESTORE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "restore";
  public static final String TAG_REVERT = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "revert";
  public static final String TAG_SET_ASSIGNEE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setAssignee";
  public static final String TAG_UPDATE_ATTENTION_SET =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "updateAttentionSet";
  public static final String TAG_SET_DESCRIPTION =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setPsDescription";
  public static final String TAG_SET_HASHTAGS = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setHashtag";
  public static final String TAG_SET_PRIVATE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setPrivate";
  public static final String TAG_SET_READY =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setReadyForReview";
  public static final String TAG_SET_TOPIC = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setTopic";
  public static final String TAG_SET_WIP = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setWorkInProgress";
  public static final String TAG_UNSET_PRIVATE =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "unsetPrivate";
  public static final String TAG_UPLOADED_PATCH_SET =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "newPatchSet";
  public static final String TAG_UPLOADED_WIP_PATCH_SET =
      AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "newWipPatchSet";

  private final AccountCache accountCache;

  @Inject
  ChangeMessagesUtil(AccountCache accountCache) {
    this.accountCache = accountCache;
  }

  /**
   * Sets {@code messageTemplate} and {@code tag}, that should be applied by the {@code update}.
   *
   * <p>The {@code messageTemplate} is persisted in storage and should not contain user identifiable
   * information. See {@link ChangeMessage}.
   *
   * @param update update that sets {@code messageTemplate}.
   * @param messageTemplate message in template form, that should be applied by the update.
   * @param tag tag that should be applied by the update.
   * @return message built from {@code messageTemplate}. Templates are replaced, so it might contain
   *     user identifiable information.
   */
  public String setChangeMessage(
      ChangeUpdate update, String messageTemplate, @Nullable String tag) {
    update.setChangeMessage(messageTemplate);
    update.setTag(tag);
    return replaceTemplates(messageTemplate);
  }

  /** See {@link #setChangeMessage(ChangeUpdate, String, String)}. */
  public String setChangeMessage(ChangeContext ctx, String messageTemplate, @Nullable String tag) {
    return setChangeMessage(
        ctx.getUpdate(ctx.getChange().currentPatchSetId()), messageTemplate, tag);
  }

  public static String uploadedPatchSetTag(boolean workInProgress) {
    return workInProgress ? TAG_UPLOADED_WIP_PATCH_SET : TAG_UPLOADED_PATCH_SET;
  }

  public static String getAccountTemplate(Account.Id accountId) {
    return String.format(ChangeMessage.ACCOUNT_TEMPLATE, accountId.get());
  }

  /** Builds user-readable message from {@code messageTemplate}. See {@link ChangeMessage}. */
  public String replaceTemplates(String messageTemplate) {
    Matcher matcher = ChangeMessage.ACCOUNT_TEMPLATE_PATTERN.matcher(messageTemplate);
    StringBuffer out = new StringBuffer();
    while (matcher.find()) {
      String accountId = matcher.group(1);
      String unrecognizedAccount = "Unrecognized Gerrit Account " + accountId;
      Optional<Account.Id> parsedAccountId = Account.Id.tryParse(accountId);
      if (!parsedAccountId.isPresent()) {
        matcher.appendReplacement(out, unrecognizedAccount);
        continue;
      }
      Optional<AccountState> account = accountCache.get(parsedAccountId.get());
      if (!account.isPresent()) {
        matcher.appendReplacement(out, unrecognizedAccount);
        continue;
      }
      matcher.appendReplacement(out, account.get().account().getNameEmail(unrecognizedAccount));
    }
    matcher.appendTail(out);
    return out.toString();
  }

  /**
   * Returns {@link ChangeMessage}s from {@link ChangeNotes}, loads {@link ChangeNotes} from data
   * storage (cache or NoteDB), if it was not loaded yet.
   */
  public List<ChangeMessage> byChange(ChangeNotes notes) {
    return notes.load().getChangeMessages();
  }

  /**
   * Replace an existing change message with the provided new message.
   *
   * <p>The ID of a change message is different between NoteDb and ReviewDb. In NoteDb, it's the
   * commit SHA-1, but in ReviewDb it was generated randomly. Taking the target message as an index
   * rather than an ID allowed us to delete the message from both NoteDb and ReviewDb.
   *
   * @param update change update.
   * @param targetMessageId the id of the target change message.
   * @param newMessage the new message which is going to replace the old.
   */
  public void replaceChangeMessage(ChangeUpdate update, String targetMessageId, String newMessage) {
    update.deleteChangeMessageByRewritingHistory(targetMessageId, newMessage);
  }

  /**
   * @param tag value of a tag, or null.
   * @return whether the tag starts with the autogenerated prefix.
   */
  public static boolean isAutogenerated(@Nullable String tag) {
    return tag != null && tag.startsWith(AUTOGENERATED_TAG_PREFIX);
  }

  public static boolean isAutogeneratedByGerrit(@Nullable String tag) {
    return tag != null && tag.startsWith(AUTOGENERATED_BY_GERRIT_TAG_PREFIX);
  }

  public static ChangeMessageInfo createChangeMessageInfo(
      ChangeMessage message, AccountLoader accountLoader) {
    PatchSet.Id patchNum = message.getPatchSetId();
    ChangeMessageInfo cmi = new ChangeMessageInfo();
    cmi.id = message.getKey().uuid();
    cmi.author = accountLoader.get(message.getAuthor());
    cmi.date = message.getWrittenOn();
    cmi.message = message.getMessage();
    cmi.tag = message.getTag();
    cmi._revisionNumber = patchNum != null ? patchNum.get() : null;
    Account.Id realAuthor = message.getRealAuthor();
    if (realAuthor != null) {
      cmi.realAuthor = accountLoader.get(realAuthor);
    }
    cmi.accountsInMessage =
        message.getAccountsInMessage().stream().map(accountLoader::get).collect(toImmutableSet());
    return cmi;
  }

  /**
   * {@link ChangeMessage} is served in template form to {@link
   * com.google.gerrit.extensions.api.changes.ChangeApi}. Serve message with replaced templates to
   * the legacy {@link com.google.gerrit.extensions.api.changes.ChangeMessageApi} endpoints.
   * TODO(mariasavtchouk): remove this, after {@link
   * com.google.gerrit.extensions.api.changes.ChangeMessageApi} is deprecated (gate with
   * experiment).
   */
  public ChangeMessageInfo createChangeMessageInfoWithReplacedTemplates(
      ChangeMessage message, AccountLoader accountLoader) {
    ChangeMessageInfo changeMessageInfo = createChangeMessageInfo(message, accountLoader);
    changeMessageInfo.message = replaceTemplates(message.getMessage());
    return changeMessageInfo;
  }
}
