// Copyright (C) 2022 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.restapi.change;

import static com.google.gerrit.server.project.ProjectCache.illegalState;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.changes.RebaseInput;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RebaseChainInfo;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.GetRelatedChangesUtil;
import com.google.gerrit.server.change.NotifyResolver;
import com.google.gerrit.server.change.RebaseChangeOp;
import com.google.gerrit.server.change.RebaseUtil;
import com.google.gerrit.server.change.RelatedChangesSorter.PatchSetData;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.git.CodeReviewCommit;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.ChangePermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevWalk;

/** Rest API for rebasing an ancestry chain of changes. */
@Singleton
public class RebaseChain
    implements RestModifyView<ChangeResource, RebaseInput>, UiAction<ChangeResource> {
  private static final ImmutableSet<ListChangesOption> OPTIONS =
      Sets.immutableEnumSet(ListChangesOption.CURRENT_REVISION, ListChangesOption.CURRENT_COMMIT);

  private final GitRepositoryManager repoManager;
  private final RebaseUtil rebaseUtil;
  private final GetRelatedChangesUtil getRelatedChangesUtil;
  private final ChangeResource.Factory changeResourceFactory;
  private final ChangeData.Factory changeDataFactory;
  private final PermissionBackend permissionBackend;
  private final BatchUpdate.Factory updateFactory;
  private final ChangeNotes.Factory notesFactory;
  private final ProjectCache projectCache;
  private final PatchSetUtil patchSetUtil;
  private final ChangeJson.Factory json;

  @Inject
  RebaseChain(
      GitRepositoryManager repoManager,
      RebaseUtil rebaseUtil,
      GetRelatedChangesUtil getRelatedChangesUtil,
      ChangeResource.Factory changeResourceFactory,
      ChangeData.Factory changeDataFactory,
      PermissionBackend permissionBackend,
      BatchUpdate.Factory updateFactory,
      ChangeNotes.Factory notesFactory,
      ProjectCache projectCache,
      PatchSetUtil patchSetUtil,
      ChangeJson.Factory json) {
    this.repoManager = repoManager;
    this.getRelatedChangesUtil = getRelatedChangesUtil;
    this.changeDataFactory = changeDataFactory;
    this.rebaseUtil = rebaseUtil;
    this.changeResourceFactory = changeResourceFactory;
    this.permissionBackend = permissionBackend;
    this.updateFactory = updateFactory;
    this.notesFactory = notesFactory;
    this.projectCache = projectCache;
    this.patchSetUtil = patchSetUtil;
    this.json = json;
  }

  @Override
  public Response<RebaseChainInfo> apply(ChangeResource tipRsrc, RebaseInput input)
      throws IOException, PermissionBackendException, RestApiException, UpdateException {
    tipRsrc.permissions().check(ChangePermission.REBASE);

    Project.NameKey project = tipRsrc.getProject();
    projectCache.get(project).orElseThrow(illegalState(project)).checkStatePermitsWrite();

    CurrentUser user = tipRsrc.getUser();

    List<Change.Id> upToDateAncestors = new ArrayList<>();
    Map<Change.Id, RebaseChangeOp> rebaseOps = new LinkedHashMap<>();
    try (Repository repo = repoManager.openRepository(project);
        ObjectInserter oi = repo.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = CodeReviewCommit.newRevWalk(reader);
        BatchUpdate bu = updateFactory.create(project, user, TimeUtil.now())) {
      List<PatchSetData> chain = getChainForCurrentPatchSet(tipRsrc);

      boolean ancestorsAreUpToDate = true;
      for (int i = 0; i < chain.size(); i++) {
        ChangeData changeData = chain.get(i).data();
        PatchSet ps = patchSetUtil.current(changeData.notes());
        if (ps == null) {
          throw new IllegalStateException(
              "current revision is missing for change " + changeData.getId());
        }

        RevisionResource revRsrc =
            new RevisionResource(changeResourceFactory.create(changeData, user), ps);
        revRsrc.permissions().check(ChangePermission.REBASE);
        rebaseUtil.verifyRebasePreconditions(rw, changeData.notes(), ps);

        boolean isUpToDate = false;
        RebaseChangeOp rebaseOp = null;
        if (i == 0) {
          ObjectId desiredBase =
              rebaseUtil.parseOrFindBaseRevision(
                  repo, rw, permissionBackend, revRsrc, input, false);
          if (currentBase(rw, ps).equals(desiredBase)) {
            isUpToDate = true;
          } else {
            rebaseOp = rebaseUtil.getRebaseOp(revRsrc, input, desiredBase);
          }
        } else {
          if (ancestorsAreUpToDate) {
            ObjectId latestCommittedBase =
                PatchSetUtil.getCurrentCommittedRevCommit(
                    project, rw, notesFactory, chain.get(i - 1).id());
            isUpToDate = currentBase(rw, ps).equals(latestCommittedBase);
          }
          if (!isUpToDate) {
            rebaseOp = rebaseUtil.getRebaseOp(revRsrc, input, chain.get(i - 1).id());
          }
        }

        if (isUpToDate) {
          upToDateAncestors.add(changeData.getId());
          continue;
        }
        ancestorsAreUpToDate = false;
        bu.addOp(revRsrc.getChange().getId(), rebaseOp);
        rebaseOps.put(revRsrc.getChange().getId(), rebaseOp);
      }

      if (ancestorsAreUpToDate) {
        throw new ResourceConflictException("The whole chain is already up to date.");
      }

      bu.setNotify(NotifyResolver.Result.none());
      bu.setRepository(repo, rw, oi);
      bu.execute();
    }

    RebaseChainInfo res = new RebaseChainInfo();
    res.rebasedChanges = new ArrayList<>();
    ChangeJson changeJson = json.create(OPTIONS);
    for (Change.Id c : upToDateAncestors) {
      res.rebasedChanges.add(changeJson.format(project, c));
    }
    for (Map.Entry<Change.Id, RebaseChangeOp> e : rebaseOps.entrySet()) {
      Change.Id id = e.getKey();
      RebaseChangeOp op = e.getValue();
      ChangeInfo changeInfo = changeJson.format(project, id);
      changeInfo.containsGitConflicts =
          !op.getRebasedCommit().getFilesWithGitConflicts().isEmpty() ? true : null;
      res.rebasedChanges.add(changeInfo);
    }
    if (res.rebasedChanges.stream()
        .anyMatch(i -> i.containsGitConflicts != null && i.containsGitConflicts)) {
      res.containsGitConflicts = true;
    }
    return Response.ok(res);
  }

  @Override
  public Description getDescription(ChangeResource tipRsrc) throws Exception {
    UiAction.Description description =
        new UiAction.Description()
            .setLabel("Rebase Chain")
            .setTitle(
                "Rebase the ancestry chain onto the tip of the target branch. Makes you the "
                    + "uploader of the changes which can affect validity of approvals.")
            .setVisible(false);

    Change tip = tipRsrc.getChange();
    if (!tip.isNew()) {
      return description;
    }
    if (!projectCache
        .get(tipRsrc.getProject())
        .orElseThrow(illegalState(tipRsrc.getProject()))
        .statePermitsWrite()) {
      return description;
    }

    if (patchSetUtil.isPatchSetLocked(tipRsrc.getNotes())) {
      return description;
    }

    boolean visible = true;
    boolean enabled = true;
    try (Repository repo = repoManager.openRepository(tipRsrc.getProject());
        RevWalk rw = new RevWalk(repo)) {
      List<PatchSetData> chain = getChainForCurrentPatchSet(tipRsrc);
      PatchSetData oldestAncestor = chain.get(0);
      if (rebaseUtil.canRebase(
          oldestAncestor.patchSet(), oldestAncestor.data().change().getDest(), repo, rw)) {
        enabled = false;
      }

      for (PatchSetData ps : chain) {
        RevisionResource psRsrc =
            new RevisionResource(
                changeResourceFactory.create(ps.data(), tipRsrc.getUser()), ps.patchSet());

        if (!psRsrc.permissions().testOrFalse(ChangePermission.REBASE)) {
          visible = false;
          break;
        }

        if (patchSetUtil.isPatchSetLocked(psRsrc.getNotes())) {
          enabled = false;
        }
        if (!RebaseUtil.hasOneParent(rw, psRsrc.getPatchSet())) {
          enabled = false;
        }
      }
    }
    return description.setVisible(visible).setEnabled(enabled);
  }

  private ObjectId currentBase(RevWalk rw, PatchSet ps) throws IOException {
    return rw.parseCommit(ps.commitId()).getParent(0);
  }

  private List<PatchSetData> getChainForCurrentPatchSet(ChangeResource rsrc)
      throws PermissionBackendException, IOException {
    return Lists.reverse(
        getRelatedChangesUtil.getAncestors(
            changeDataFactory.create(rsrc.getNotes()),
            patchSetUtil.current(rsrc.getNotes()),
            true));
  }
}
