// Copyright (C) 2015 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.googlesource.gerrit.plugins.importer;

import static com.google.gerrit.server.CommentsUtil.setCommentRevId;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.NoSuchAccountException;
import com.google.gerrit.extensions.client.Side;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.CommentInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Comment;
import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.config.GerritServerId;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ReplayInlineCommentsStep {

  interface Factory {
    ReplayInlineCommentsStep create(
        Change change, ChangeInfo changeInfo, GerritApi api, boolean resume);
  }

  private static final Logger log = LoggerFactory.getLogger(ReplayInlineCommentsStep.class);

  private final AccountUtil accountUtil;
  private final ReviewDb db;
  private final IdentifiedUser.GenericFactory genericUserFactory;
  private final ChangeControl.GenericFactory changeControlFactory;
  private final ChangeUpdate.Factory updateFactory;
  private final CommentsUtil commentsUtil;
  private final PatchListCache patchListCache;
  private final PatchSetUtil psUtil;
  private final String serverId;
  private final Change change;
  private final ChangeInfo changeInfo;
  private final GerritApi api;
  private final boolean resume;

  @Inject
  public ReplayInlineCommentsStep(
      AccountUtil accountUtil,
      ReviewDb db,
      IdentifiedUser.GenericFactory genericUserFactory,
      ChangeControl.GenericFactory changeControlFactory,
      ChangeUpdate.Factory updateFactory,
      CommentsUtil commentsUtil,
      PatchListCache patchListCache,
      PatchSetUtil psUtil,
      @GerritServerId String serverId,
      @Assisted Change change,
      @Assisted ChangeInfo changeInfo,
      @Assisted GerritApi api,
      @Assisted boolean resume) {
    this.accountUtil = accountUtil;
    this.db = db;
    this.genericUserFactory = genericUserFactory;
    this.changeControlFactory = changeControlFactory;
    this.updateFactory = updateFactory;
    this.commentsUtil = commentsUtil;
    this.patchListCache = patchListCache;
    this.psUtil = psUtil;
    this.serverId = serverId;
    this.change = change;
    this.changeInfo = changeInfo;
    this.api = api;
    this.resume = resume;
  }

  void replay()
      throws RestApiException, OrmException, IOException, NoSuchChangeException,
          NoSuchAccountException, ConfigInvalidException {
    ChangeControl ctrl = control(change, change.getOwner());
    for (PatchSet ps : ChangeUtil.PS_ID_ORDER.sortedCopy(psUtil.byChange(db, ctrl.getNotes()))) {
      Iterable<CommentInfo> comments = api.getComments(changeInfo._number, ps.getRevision().get());
      if (resume) {
        if (comments == null) {
          // the revision does not exist in the source system,
          // it must be a revision that was created in the target system after
          // the initial import
          log.warn(
              String.format(
                  "Project %s was modified in target system: "
                      + "Skip replay inline comments for patch set %s"
                      + " which doesn't exist in the source system.",
                  change.getProject().get(), ps.getId().toString()));
          continue;
        }

        comments = filterComments(ps, comments);
      } else if (comments == null) {
        log.warn(
            String.format(
                "Cannot retrieve comments for revision %s, "
                    + "revision not found in source system: "
                    + "Skip replay inline comments for patch set %s of project %s.",
                ps.getRevision().get(), ps.getId().toString(), change.getProject().get()));
        continue;
      }

      Multimap<Account.Id, CommentInfo> commentsByAuthor = ArrayListMultimap.create();
      for (CommentInfo comment : comments) {
        Account.Id id = accountUtil.resolveUser(api, comment.author);
        commentsByAuthor.put(id, comment);
      }

      for (Account.Id id : commentsByAuthor.keySet()) {
        insertComments(ps, id, commentsByAuthor.get(id));
      }
    }
  }

  private Iterable<CommentInfo> filterComments(PatchSet ps, Iterable<CommentInfo> comments)
      throws OrmException {
    Set<String> existingUuids = new HashSet<>();
    for (PatchLineComment c : db.patchComments().byPatchSet(ps.getId())) {
      existingUuids.add(c.getKey().get());
    }

    Iterator<CommentInfo> it = comments.iterator();
    while (it.hasNext()) {
      CommentInfo c = it.next();
      if (existingUuids.contains(Url.decode(c.id))) {
        it.remove();
      }
    }
    return comments;
  }

  private void insertComments(PatchSet ps, Account.Id author, Collection<CommentInfo> comments)
      throws OrmException, IOException, NoSuchChangeException {
    ChangeControl ctrl = control(change, author);

    Map<String, Comment> drafts = scanDraftComments(ctrl, ps);

    List<Comment> del = Lists.newArrayList();
    List<Comment> ups = Lists.newArrayList();

    for (CommentInfo c : comments) {
      String parent = Url.decode(c.inReplyTo);
      Comment e = drafts.remove(Url.decode(c.id));

      if (e == null) {
        e =
            new Comment(
                new Comment.Key(Url.decode(c.id), c.path, ps.getId().get()),
                author,
                c.updated,
                c.side == Side.PARENT ? (short) 0 : (short) 1,
                c.message,
                serverId,
                c.unresolved == null ? false : c.unresolved);
      } else if (parent != null) {
        e.parentUuid = parent;
      }
      setCommentRevId(e, patchListCache, change, ps);
      if (c.range != null) {
        e.setRange(
            new CommentRange(
                c.range.startLine, c.range.startCharacter, c.range.endLine, c.range.endCharacter));
        e.lineNbr = c.range.endLine;
      } else {
        e.lineNbr = c.line == null ? 0 : c.line;
      }
      ups.add(e);
    }

    Iterables.addAll(del, drafts.values());
    ChangeUpdate update = updateFactory.create(ctrl, TimeUtil.nowTs());
    update.setPatchSetId(ps.getId());

    commentsUtil.deleteComments(db, update, del);
    commentsUtil.putComments(db, update, Status.PUBLISHED, ups);
    update.commit();
  }

  private Map<String, Comment> scanDraftComments(ChangeControl ctrl, PatchSet ps)
      throws OrmException {
    Map<String, Comment> drafts = Maps.newHashMap();
    for (Comment c :
        commentsUtil.draftByPatchSetAuthor(
            db, ps.getId(), ((IdentifiedUser) ctrl.getUser()).getAccountId(), ctrl.getNotes())) {
      drafts.put(c.key.uuid, c);
    }
    return drafts;
  }

  private ChangeControl control(Change change, Account.Id id) throws NoSuchChangeException {
    try {
      return changeControlFactory.controlFor(db, change, genericUserFactory.create(id));
    } catch (OrmException e) {
      throw new NoSuchChangeException(change.getId());
    }
  }
}
