// Copyright (C) 2020 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.acceptance.testsuite.change;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.google.gerrit.entities.Account;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResolver;
import com.google.gerrit.server.change.ChangeFinder;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.edit.tree.TreeCreator;
import com.google.gerrit.server.edit.tree.TreeModification;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.Sequences;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.CommitMessageUtil;
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.util.ChangeIdUtil;

/**
 * The implementation of {@link ChangeOperations}.
 *
 * <p>There is only one implementation of {@link ChangeOperations}. Nevertheless, we keep the
 * separation between interface and implementation to enhance clarity.
 */
public class ChangeOperationsImpl implements ChangeOperations {
  private final Sequences seq;
  private final ChangeInserter.Factory changeInserterFactory;
  private final PatchSetInserter.Factory patchsetInserterFactory;
  private final GitRepositoryManager repositoryManager;
  private final AccountResolver resolver;
  private final IdentifiedUser.GenericFactory userFactory;
  private final PersonIdent serverIdent;
  private final BatchUpdate.Factory batchUpdateFactory;
  private final ProjectCache projectCache;
  private final ChangeFinder changeFinder;
  private final PerPatchsetOperationsImpl.Factory perPatchsetOperationsFactory;

  @Inject
  public ChangeOperationsImpl(
      Sequences seq,
      ChangeInserter.Factory changeInserterFactory,
      PatchSetInserter.Factory patchsetInserterFactory,
      GitRepositoryManager repositoryManager,
      AccountResolver resolver,
      IdentifiedUser.GenericFactory userFactory,
      @GerritPersonIdent PersonIdent serverIdent,
      BatchUpdate.Factory batchUpdateFactory,
      ProjectCache projectCache,
      ChangeFinder changeFinder,
      PerPatchsetOperationsImpl.Factory perPatchsetOperationsFactory) {
    this.seq = seq;
    this.changeInserterFactory = changeInserterFactory;
    this.patchsetInserterFactory = patchsetInserterFactory;
    this.repositoryManager = repositoryManager;
    this.resolver = resolver;
    this.userFactory = userFactory;
    this.serverIdent = serverIdent;
    this.batchUpdateFactory = batchUpdateFactory;
    this.projectCache = projectCache;
    this.changeFinder = changeFinder;
    this.perPatchsetOperationsFactory = perPatchsetOperationsFactory;
  }

  @Override
  public PerChangeOperations change(Change.Id changeId) {
    return new PerChangeOperationsImpl(changeId);
  }

  @Override
  public TestChangeCreation.Builder newChange() {
    return TestChangeCreation.builder(this::createChange);
  }

  private Change.Id createChange(TestChangeCreation changeCreation) throws Exception {
    Change.Id changeId = Change.id(seq.nextChangeId());
    Project.NameKey project = getTargetProject(changeCreation);

    try (Repository repository = repositoryManager.openRepository(project);
        ObjectInserter objectInserter = repository.newObjectInserter();
        RevWalk revWalk = new RevWalk(objectInserter.newReader())) {
      Timestamp now = TimeUtil.nowTs();
      IdentifiedUser changeOwner = getChangeOwner(changeCreation);
      PersonIdent authorAndCommitter =
          changeOwner.newCommitterIdent(now, serverIdent.getTimeZone());
      ObjectId commitId =
          createCommit(repository, revWalk, objectInserter, changeCreation, authorAndCommitter);

      String refName = RefNames.fullName(changeCreation.branch());
      ChangeInserter inserter = getChangeInserter(changeId, refName, commitId);

      try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, changeOwner, now)) {
        batchUpdate.setRepository(repository, revWalk, objectInserter);
        batchUpdate.insertChange(inserter);
        batchUpdate.execute();
      }
      return changeId;
    }
  }

  private Project.NameKey getTargetProject(TestChangeCreation changeCreation) {
    if (changeCreation.project().isPresent()) {
      return changeCreation.project().get();
    }

    return getArbitraryProject();
  }

  private Project.NameKey getArbitraryProject() {
    Project.NameKey allProjectsName = projectCache.getAllProjects().getNameKey();
    Project.NameKey allUsersName = projectCache.getAllUsers().getNameKey();
    Optional<Project.NameKey> arbitraryProject =
        projectCache.all().stream()
            .filter(
                name ->
                    !Objects.equals(name, allProjectsName) && !Objects.equals(name, allUsersName))
            .findFirst();
    checkState(
        arbitraryProject.isPresent(),
        "At least one repository must be available on the Gerrit server");
    return arbitraryProject.get();
  }

  private IdentifiedUser getChangeOwner(TestChangeCreation changeCreation)
      throws IOException, ConfigInvalidException {
    if (changeCreation.owner().isPresent()) {
      return userFactory.create(changeCreation.owner().get());
    }

    return getArbitraryUser();
  }

  private IdentifiedUser getArbitraryUser() throws ConfigInvalidException, IOException {
    ImmutableSet<Account.Id> foundAccounts = resolver.resolveIgnoreVisibility("").asIdSet();
    checkState(
        !foundAccounts.isEmpty(),
        "At least one user account must be available on the Gerrit server");
    return userFactory.create(foundAccounts.iterator().next());
  }

  private ObjectId createCommit(
      Repository repository,
      RevWalk revWalk,
      ObjectInserter objectInserter,
      TestChangeCreation changeCreation,
      PersonIdent authorAndCommitter)
      throws IOException, BadRequestException {
    Optional<ObjectId> branchTip = getTip(repository, changeCreation.branch());

    ObjectId tree =
        createNewTree(
            repository,
            revWalk,
            branchTip.orElse(ObjectId.zeroId()),
            changeCreation.treeModifications());

    String commitMessage = correctCommitMessage(changeCreation.commitMessage());

    ImmutableList<ObjectId> parentCommitIds = Streams.stream(branchTip).collect(toImmutableList());
    return createCommit(
        objectInserter,
        tree,
        parentCommitIds,
        authorAndCommitter,
        authorAndCommitter,
        commitMessage);
  }

  private Optional<ObjectId> getTip(Repository repository, String branch) throws IOException {
    Optional<Ref> ref = Optional.ofNullable(repository.findRef(branch));
    return ref.map(Ref::getObjectId);
  }

  private static ObjectId createNewTree(
      Repository repository,
      RevWalk revWalk,
      ObjectId baseCommitId,
      ImmutableList<TreeModification> treeModifications)
      throws IOException {
    TreeCreator treeCreator = getTreeCreator(revWalk, baseCommitId);
    treeCreator.addTreeModifications(treeModifications);
    return treeCreator.createNewTreeAndGetId(repository);
  }

  private static TreeCreator getTreeCreator(RevWalk revWalk, ObjectId baseCommitId)
      throws IOException {
    if (ObjectId.zeroId().equals(baseCommitId)) {
      return TreeCreator.basedOnEmptyTree();
    }
    RevCommit baseCommit = revWalk.parseCommit(baseCommitId);
    return TreeCreator.basedOn(baseCommit);
  }

  private String correctCommitMessage(String desiredCommitMessage) throws BadRequestException {
    String commitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(desiredCommitMessage);

    if (ChangeIdUtil.indexOfChangeId(commitMessage, "\n") == -1) {
      ObjectId id = CommitMessageUtil.generateChangeId();
      commitMessage = ChangeIdUtil.insertId(commitMessage, id);
    }

    return commitMessage;
  }

  private ObjectId createCommit(
      ObjectInserter objectInserter,
      ObjectId tree,
      ImmutableList<ObjectId> parentCommitIds,
      PersonIdent author,
      PersonIdent committer,
      String commitMessage)
      throws IOException {
    CommitBuilder builder = new CommitBuilder();
    builder.setTreeId(tree);
    builder.setParentIds(parentCommitIds);
    builder.setAuthor(author);
    builder.setCommitter(committer);
    builder.setMessage(commitMessage);
    ObjectId newCommitId = objectInserter.insert(builder);
    objectInserter.flush();
    return newCommitId;
  }

  private ChangeInserter getChangeInserter(Change.Id changeId, String refName, ObjectId commitId) {
    ChangeInserter inserter = changeInserterFactory.create(changeId, commitId, refName);
    inserter.setMessage(String.format("Uploaded patchset %d.", inserter.getPatchSetId().get()));
    return inserter;
  }

  private class PerChangeOperationsImpl implements PerChangeOperations {

    private final Change.Id changeId;

    public PerChangeOperationsImpl(Change.Id changeId) {
      this.changeId = changeId;
    }

    @Override
    public boolean exists() {
      return changeFinder.findOne(changeId).isPresent();
    }

    @Override
    public TestChange get() {
      return toTestChange(getChangeNotes().getChange());
    }

    private ChangeNotes getChangeNotes() {
      Optional<ChangeNotes> changeNotes = changeFinder.findOne(changeId);
      checkState(changeNotes.isPresent(), "Tried to get non-existing test change.");
      return changeNotes.get();
    }

    private TestChange toTestChange(Change change) {
      return TestChange.builder()
          .numericChangeId(change.getId())
          .changeId(change.getKey().get())
          .build();
    }

    @Override
    public TestPatchsetCreation.Builder newPatchset() {
      return TestPatchsetCreation.builder(this::createPatchset);
    }

    private PatchSet.Id createPatchset(TestPatchsetCreation patchsetCreation)
        throws IOException, RestApiException, UpdateException {
      ChangeNotes changeNotes = getChangeNotes();
      Project.NameKey project = changeNotes.getProjectName();
      try (Repository repository = repositoryManager.openRepository(project);
          ObjectInserter objectInserter = repository.newObjectInserter();
          RevWalk revWalk = new RevWalk(objectInserter.newReader())) {
        Timestamp now = TimeUtil.nowTs();
        ObjectId newPatchsetCommit =
            createPatchsetCommit(
                repository, revWalk, objectInserter, changeNotes, patchsetCreation, now);

        PatchSet.Id patchsetId =
            ChangeUtil.nextPatchSetId(repository, changeNotes.getCurrentPatchSet().id());
        PatchSetInserter patchSetInserter =
            getPatchSetInserter(changeNotes, newPatchsetCommit, patchsetId);

        IdentifiedUser changeOwner = userFactory.create(changeNotes.getChange().getOwner());
        try (BatchUpdate batchUpdate = batchUpdateFactory.create(project, changeOwner, now)) {
          batchUpdate.setRepository(repository, revWalk, objectInserter);
          batchUpdate.addOp(changeId, patchSetInserter);
          batchUpdate.execute();
        }
        return patchsetId;
      }
    }

    private ObjectId createPatchsetCommit(
        Repository repository,
        RevWalk revWalk,
        ObjectInserter objectInserter,
        ChangeNotes changeNotes,
        TestPatchsetCreation patchsetCreation,
        Timestamp now)
        throws IOException {
      ObjectId oldPatchsetCommitId = changeNotes.getCurrentPatchSet().commitId();
      RevCommit oldPatchsetCommit = repository.parseCommit(oldPatchsetCommitId);

      ObjectId tree =
          createNewTree(
              repository, revWalk, oldPatchsetCommitId, patchsetCreation.treeModifications());

      String commitMessage = oldPatchsetCommit.getFullMessage();

      ImmutableList<ObjectId> parentCommitIds = getParents(oldPatchsetCommit);
      PersonIdent author = getAuthor(oldPatchsetCommit);
      PersonIdent committer = getCommitter(oldPatchsetCommit, now);
      return createCommit(objectInserter, tree, parentCommitIds, author, committer, commitMessage);
    }

    private PersonIdent getAuthor(RevCommit oldPatchsetCommit) {
      return Optional.ofNullable(oldPatchsetCommit.getAuthorIdent()).orElse(serverIdent);
    }

    private PersonIdent getCommitter(RevCommit oldPatchsetCommit, Timestamp now) {
      PersonIdent oldPatchsetCommitter =
          Optional.ofNullable(oldPatchsetCommit.getCommitterIdent()).orElse(serverIdent);
      if (asSeconds(now) == asSeconds(oldPatchsetCommitter.getWhen())) {
        /* We need to ensure that the resulting commit SHA-1 is different from the old patchset.
         * In real situations, this automatically happens as two patchsets won't have exactly the
         * same commit timestamp even when the tree and commit message are the same. In tests,
         * we can easily end up with the same timestamp as Git uses second precision for timestamps.
         * We could of course require that tests must use TestTimeUtil#setClockStep but
         * that would be an unnecessary nuisance for test writers. Hence, go with a simple solution
         * here and simply add a second. */
        now = Timestamp.from(now.toInstant().plusSeconds(1));
      }
      return new PersonIdent(oldPatchsetCommitter, now);
    }

    private long asSeconds(Date date) {
      return date.getTime() / 1000;
    }

    private ImmutableList<ObjectId> getParents(RevCommit oldPatchsetCommit) {
      return Arrays.stream(oldPatchsetCommit.getParents())
          .map(ObjectId::toObjectId)
          .collect(toImmutableList());
    }

    private PatchSetInserter getPatchSetInserter(
        ChangeNotes changeNotes, ObjectId newPatchsetCommit, PatchSet.Id patchsetId) {
      PatchSetInserter patchSetInserter =
          patchsetInserterFactory.create(changeNotes, patchsetId, newPatchsetCommit);
      patchSetInserter.setCheckAddPatchSetPermission(false);
      patchSetInserter.setMessage(String.format("Uploaded patchset %d.", patchsetId.get()));
      return patchSetInserter;
    }

    @Override
    public PerPatchsetOperations patchset(PatchSet.Id patchsetId) {
      return perPatchsetOperationsFactory.create(getChangeNotes(), patchsetId);
    }

    @Override
    public PerPatchsetOperations currentPatchset() {
      ChangeNotes changeNotes = getChangeNotes();
      return perPatchsetOperationsFactory.create(
          changeNotes, changeNotes.getChange().currentPatchSetId());
    }
  }
}
