// 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 com.google.common.collect.Iterators;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.errors.NoSuchAccountException;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.Sequences;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.update.UpdateException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ReplayChangesStep {

  interface Factory {
    ReplayChangesStep create(
        @Nullable String fromGerrit,
        GerritApi api,
        Repository repo,
        @Assisted("srcProject") Project.NameKey srcProject,
        @Assisted("targetProject") Project.NameKey targetProject,
        @Assisted("force") boolean force,
        @Assisted("resume") boolean resume,
        ResumeImportStatistic importStatistic,
        ProgressMonitor pm);
  }

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

  private final ReplayRevisionsStep.Factory replayRevisionsFactory;
  private final ReplayInlineCommentsStep.Factory replayInlineCommentsFactory;
  private final ReplayMessagesStep.Factory replayMessagesFactory;
  private final AddApprovalsStep.Factory addApprovalsFactory;
  private final AddHashtagsStep.Factory addHashtagsFactory;
  private final InsertLinkToOriginalChangeStep.Factory insertLinkToOriginalFactory;
  private final AccountUtil accountUtil;
  private final ReviewDb db;
  private final ChangeIndexer indexer;
  private final Provider<InternalChangeQuery> queryProvider;
  private final Sequences sequences;
  private final String fromGerrit;
  private final GerritApi api;
  private final Repository repo;
  private final Project.NameKey srcProject;
  private final Project.NameKey targetProject;
  private final boolean force;
  private final boolean resume;
  private final ResumeImportStatistic importStatistic;
  private final ProgressMonitor pm;
  private final boolean isNoteDbEnabled;

  @Inject
  ReplayChangesStep(
      ReplayRevisionsStep.Factory replayRevisionsFactory,
      ReplayInlineCommentsStep.Factory replayInlineCommentsFactory,
      ReplayMessagesStep.Factory replayMessagesFactory,
      AddApprovalsStep.Factory addApprovalsFactory,
      AddHashtagsStep.Factory addHashtagsFactory,
      InsertLinkToOriginalChangeStep.Factory insertLinkToOriginalFactory,
      AccountUtil accountUtil,
      ReviewDb db,
      ChangeIndexer indexer,
      Provider<InternalChangeQuery> queryProvider,
      Sequences sequences,
      NotesMigration migration,
      @Assisted @Nullable String fromGerrit,
      @Assisted GerritApi api,
      @Assisted Repository repo,
      @Assisted("srcProject") Project.NameKey srcProject,
      @Assisted("targetProject") Project.NameKey targetProject,
      @Assisted("force") boolean force,
      @Assisted("resume") boolean resume,
      @Assisted ResumeImportStatistic importStatistic,
      @Assisted ProgressMonitor pm) {
    this.replayRevisionsFactory = replayRevisionsFactory;
    this.replayInlineCommentsFactory = replayInlineCommentsFactory;
    this.replayMessagesFactory = replayMessagesFactory;
    this.addApprovalsFactory = addApprovalsFactory;
    this.addHashtagsFactory = addHashtagsFactory;
    this.insertLinkToOriginalFactory = insertLinkToOriginalFactory;
    this.accountUtil = accountUtil;
    this.db = db;
    this.indexer = indexer;
    this.queryProvider = queryProvider;
    this.sequences = sequences;
    this.fromGerrit = fromGerrit;
    this.api = api;
    this.repo = repo;
    this.srcProject = srcProject;
    this.targetProject = targetProject;
    this.force = force;
    this.resume = resume;
    this.importStatistic = importStatistic;
    this.pm = pm;
    this.isNoteDbEnabled = migration.readChanges();
  }

  void replay()
      throws IOException, OrmException, NoSuchAccountException, NoSuchChangeException,
          RestApiException, UpdateException, ConfigInvalidException,
          PatchListNotAvailableException {
    int start = 0;
    int limit = GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
    pm.beginTask("Replay Changes", ProgressMonitor.UNKNOWN);
    for (; ; ) {
      List<ChangeInfo> changes = api.queryChanges(srcProject.get(), start, limit);
      if (changes.isEmpty()) {
        break;
      }
      start += changes.size();
      try (RevWalk rw = new RevWalk(repo)) {
        ChangeInfo last = null;
        for (ChangeInfo c : changes) {
          try {
            replayChange(rw, c);
          } catch (Exception e) {
            log.error(String.format("Failed to replay change %s.", Url.decode(c.id)), e);
            throw e;
          }
          last = c;
          pm.update(1);
        }
        if (!Boolean.TRUE.equals(last._moreChanges)) {
          break;
        }
      }
    }
    pm.endTask();
  }

  private void replayChange(RevWalk rw, ChangeInfo c)
      throws IOException, OrmException, NoSuchAccountException, NoSuchChangeException,
          RestApiException, IllegalArgumentException, UpdateException, ConfigInvalidException,
          PatchListNotAvailableException {
    Change change = resume ? findChange(c) : null;
    boolean resumeChange;
    if (change == null) {
      resumeChange = false;
      change = createChange(c);
    } else {
      resumeChange = true;
      if (!force && change.getLastUpdatedOn().equals(c.updated)) {
        // change was not modified since last import
        return;
      }
    }

    if (c.revisions.isEmpty()) {
      log.warn(String.format("Change %s has no revisions.", c.id));
      return;
    }

    replayRevisionsFactory.create(repo, rw, change, c).replay(api);
    upsertChange(resumeChange, change, c);

    replayInlineCommentsFactory.create(change, c, api, resumeChange).replay();
    replayMessagesFactory.create(change, c, resumeChange).replay(api);
    addApprovalsFactory.create(change, c, resume).add(api);
    if (isNoteDbEnabled) {
      addHashtagsFactory.create(change, c, resumeChange).add();
    }

    insertLinkToOriginalFactory.create(fromGerrit, change, c, resumeChange).insert();

    indexer.index(db, change);

    if (resumeChange) {
      importStatistic.numChangesUpdated++;
    } else {
      importStatistic.numChangesCreated++;
    }
  }

  private Change findChange(ChangeInfo c) throws OrmException {
    List<Change> changes =
        ChangeData.asChanges(
            queryProvider
                .get()
                .byBranchKey(
                    new Branch.NameKey(targetProject, RefNames.fullName(c.branch)),
                    new Change.Key(c.changeId)));
    if (changes.isEmpty()) {
      return null;
    }
    return db.changes().get(Iterators.getOnlyElement(changes.iterator()).getId());
  }

  private Change createChange(ChangeInfo c)
      throws OrmException, NoSuchAccountException, IOException, RestApiException,
          ConfigInvalidException {
    Change.Id changeId = new Change.Id(sequences.nextChangeId());

    Change change =
        new Change(
            new Change.Key(c.changeId),
            changeId,
            accountUtil.resolveUser(api, c.owner),
            new Branch.NameKey(targetProject, RefNames.fullName(c.branch)),
            c.created);
    change.setStatus(Change.Status.forChangeStatus(c.status));
    change.setTopic(c.topic);
    change.setLastUpdatedOn(c.updated);
    return change;
  }

  private void upsertChange(boolean resumeChange, Change change, ChangeInfo c) throws OrmException {
    if (resumeChange) {
      change.setStatus(Change.Status.forChangeStatus(c.status));
      change.setTopic(c.topic);
      change.setLastUpdatedOn(c.updated);
    }
    db.changes().upsert(Collections.singleton(change));
  }
}
