// Copyright 2014 Criteo
//
// 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.criteo.gerrit.plugins.automerge;

import com.google.common.collect.Lists;
import com.google.gerrit.common.EventListener;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.GetRelated;
import com.google.gerrit.server.change.PostReview;
import com.google.gerrit.server.change.Submit;
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.events.ChangeEvent;
import com.google.gerrit.server.events.CommentAddedEvent;
import com.google.gerrit.server.events.Event;
import com.google.gerrit.server.events.PatchSetCreatedEvent;
import com.google.gerrit.server.events.RefUpdatedEvent;
import com.google.gerrit.server.events.TopicChangedEvent;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.EnumSet;
import java.util.List;

/**
 * Starts at the same time as the gerrit server, and sets up our change hook
 * listener.
 */
public class AutomaticMerger implements EventListener, LifecycleListener {

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

  @Inject
  private GerritApi api;

  @Inject
  private AtomicityHelper atomicityHelper;

  @Inject
  ChangeData.Factory changeDataFactory;

  @Inject
  private AutomergeConfig config;

  @Inject
  Provider<ReviewDb> db;

  @Inject
  GetRelated getRelated;

  @Inject
  MergeUtil.Factory mergeUtilFactory;

  @Inject
  Provider<PostReview> reviewer;

  @Inject
  private ReviewUpdater reviewUpdater;

  @Inject
  Submit submitter;

  @Override
  synchronized public void onEvent(final Event event) {
    if (event instanceof TopicChangedEvent ||
        event instanceof PatchSetCreatedEvent) {
      Change change = Change.from(((ChangeEvent)event).change.get());
      onNewOrChangedPatchSet(change);
    }
    else if (event instanceof CommentAddedEvent) {
      onCommentAdded((CommentAddedEvent)event);
    }
    // it is not an else since the previous automatic submit(s) can potentially
    // trigger others on the whole project/branch
    if (event instanceof RefUpdatedEvent) {
      onRefUpdatedEvent((RefUpdatedEvent) event);
    }
  }

  private void onNewOrChangedPatchSet(Change change) {
    if (atomicityHelper.isAtomicReview(change)) {
      processNewAtomicPatchSet(change);
    }
    try {
      autoSubmitIfMergeable(change);
    } catch (OrmException | RestApiException | IOException | UpdateException e) {
      log.error("An exception occured while trying to merge change #" + change.number, e);
    }
  }

  private void onCommentAdded(final CommentAddedEvent newComment) {
    if (!shouldProcessCommentEvent(newComment)) {
      return;
    }

    ChangeAttribute change = newComment.change.get();
    try {
      checkReviewExists(change.number);
      autoSubmitIfMergeable(Change.from(change));
    } catch (RestApiException | OrmException | UpdateException | IOException e) {
      log.error("An exception occured while trying to atomic merge a change.", e);
      throw new RuntimeException(e);
    }
  }

  private void onRefUpdatedEvent(final RefUpdatedEvent event) {
    String refName = event.getRefName();
    String projectName = event.getProjectNameKey().get();
    try {
      api.changes()
          .query("branch:" + refName + " project:" + projectName + " is:submittable")
          .get()
          .forEach(
              submittable -> {
                try {
                  log.info(
                      "Found another submittable change #"
                          + submittable._number
                          + " on project "
                          + projectName
                          + " during update of ref "
                          + refName
                          + ": Submitting ...");
                  autoSubmitIfMergeable(Change.from(submittable));
                } catch (UpdateException | RestApiException | OrmException | IOException e) {
                  log.error(
                      "Cannot autosubmit change "
                          + submittable._number
                          + " on project "
                          + projectName
                          + " to ref "
                          + refName,
                      e);
                }
              });
    } catch (RestApiException e) {
      log.error(
          "Cannot query submittable changes on project " + projectName + " for ref " + refName);
    }
  }

  private void autoSubmitIfMergeable(Change change)
      throws OrmException, RestApiException, NoSuchChangeException, IOException, UpdateException {
    if (atomicityHelper.isSubmittable(change.project, change.number)) {
      if (atomicityHelper.isAtomicReview(change)) {
        attemptToMergeAtomic(change);
      } else {
        log.info("Submitting non-atomic change {}...", change.number);
        atomicityHelper.mergeReview(change.project, change.number);
      }
    }
  }

  /**
   * Returns true if the plugin must handle this comment, i.e. if we are sure it does not come
   * from this plugin (to avoid infinite loop).
   *
   * @param comment
   * @return a boolean
   */
  private boolean shouldProcessCommentEvent(CommentAddedEvent comment) {
    AccountAttribute account = comment.author.get();
    if (!config.getBotEmail().equals(account.email)) {
      return true;
    }
    if (!comment.comment.contains(ReviewUpdater.commentsPrefix)) {
      return true;
    }
    return false;
  }

  private void attemptToMergeAtomic(Change change)
      throws RestApiException, OrmException, NoSuchChangeException, IOException, UpdateException {
    final List<ChangeInfo> related = Lists.newArrayList();
    related.addAll(
        api.changes()
            .query("status: open AND topic: " + change.topic)
            .withOption(ListChangesOption.CURRENT_REVISION)
            .get());
    for (final ChangeInfo info : related) {
      if (!atomicityHelper.isSubmittable(info.project, info._number)) {
        log.info("Change {} is not submittable because same topic change {} has not all approvals.", change.number, info._number);
        return;
      }
    }

    for (final ChangeInfo info : related) {
      boolean dependsOnNonMergedCommit = atomicityHelper.hasDependentReview(info.project, info._number);
      if (!info.mergeable || dependsOnNonMergedCommit) {
        log.info("Change {} is not mergeable because same topic change {} {}", change.number, info._number,
            !info.mergeable ? "is non mergeable" : "depends on a non merged commit.");
        PluginComment comment = !info.mergeable ? config.cantMergeGitConflict : config.cantMergeDependsOnNonMerged;
        reviewUpdater.commentOnReview(change.project, change.number, String.format(comment.getContent(), info._number));
        return;
      }
    }

    log.info("Submitting atomic change {}...", change.number);
    for (final ChangeInfo info : related) {
      atomicityHelper.mergeReview(info.project, info._number);
    }
  }

  private void processNewAtomicPatchSet(Change change) {
    try {
      checkReviewExists(change.number);
      log.info(String.format("Detected atomic review on change %d.", change.number));
      reviewUpdater.commentOnReview(change.project, change.number, config.atomicReviewDetected.getContent());
      if (atomicityHelper.hasDependentReview(change.project, change.number)) {
        log.info(String.format("Warn the user on change %d, as other atomic changes exists on the same repository.",
            change.number));
        reviewUpdater.commentOnReview(change.project, change.number, config.atomicReviewsSameRepo.getContent());
      }
    } catch (RestApiException | IOException | OrmException | UpdateException e) {
      throw new RuntimeException(e);
    }
  }

  private void checkReviewExists(int reviewNumber) throws RestApiException {
    api.changes().id(reviewNumber).get(EnumSet.of(ListChangesOption.CURRENT_REVISION));
  }

  @Override
  public void start() {
    log.info("Starting automatic merger plugin.");
  }

  @Override
  public void stop() {
  }
}
