// Copyright (C) 2012 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.github.git;

import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Change.Id;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.PatchSetInserter;
import com.google.gerrit.server.change.PatchSetInserter.ValidatePolicy;
import com.google.gerrit.server.events.CommitReceivedEvent;
import com.google.gerrit.server.git.MergeException;
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefControl;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.ssh.NoSshInfo;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.ReceiveCommand;
import org.eclipse.jgit.util.ChangeIdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

public class PullRequestCreateChange {
  private static final Logger LOG = LoggerFactory
      .getLogger(PullRequestCreateChange.class);
  private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");

  private final IdentifiedUser currentUser;
  private final CommitValidators.Factory commitValidatorsFactory;
  private final ChangeInserter.Factory changeInserterFactory;
  private final PatchSetInserter.Factory patchSetInserterFactory;
  private final ProjectControl.Factory projectControlFactory;
  private final GenericFactory userFactory;
  private final Provider<InternalChangeQuery> queryProvider;

  @Inject
  PullRequestCreateChange(IdentifiedUser currentUser,
      CommitValidators.Factory commitValidatorsFactory,
      ChangeInserter.Factory changeInserterFactory,
      PatchSetInserter.Factory patchSetInserterFactory,
      ProjectControl.Factory projectControlFactory,
      IdentifiedUser.GenericFactory userFactory,
      Provider<InternalChangeQuery> queryProvider) {
    this.currentUser = currentUser;
    this.commitValidatorsFactory = commitValidatorsFactory;
    this.changeInserterFactory = changeInserterFactory;
    this.patchSetInserterFactory = patchSetInserterFactory;
    this.projectControlFactory = projectControlFactory;
    this.userFactory = userFactory;
    this.queryProvider = queryProvider;
  }

  public Change.Id addCommitToChange(final ReviewDb db, final Project project,
      final Repository git, final String destinationBranch,
      final Account.Id pullRequestOwner, final RevCommit pullRequestCommit,
      final String pullRequestMesage, final String topic, boolean doValidation)
      throws NoSuchChangeException, EmailException, OrmException,
      MissingObjectException, IncorrectObjectTypeException, IOException,
      InvalidChangeOperationException, MergeException, NoSuchProjectException {
    Id newChange = null;
    if (destinationBranch == null || destinationBranch.length() == 0) {
      throw new InvalidChangeOperationException(
          "Destination branch cannot be null or empty");
    }

    RefControl refControl =
        projectControlFactory.controlFor(project.getNameKey()).controlForRef(
            destinationBranch);

    try (RevWalk revWalk = new RevWalk(git)) {
      try {
        Ref destRef = git.getRef(destinationBranch);
        if (destRef == null) {
          throw new InvalidChangeOperationException("Branch "
              + destinationBranch + " does not exist.");
        }

        String pullRequestSha1 = pullRequestCommit.getId().getName();
        ResultSet<PatchSet> existingPatchSet =
            db.patchSets().byRevision(new RevId(pullRequestSha1));
        Iterator<PatchSet> patchSetIterator = existingPatchSet.iterator();
        if (patchSetIterator.hasNext()) {
          PatchSet patchSet = patchSetIterator.next();
          LOG.debug("Pull request commit ID " + pullRequestSha1
              + " has been already uploaded as PatchSetID="
              + patchSet.getPatchSetId() + " in ChangeID=" + patchSet.getId());
          return null;
        }

        Change.Key changeKey;
        final List<String> idList = pullRequestCommit.getFooterLines(CHANGE_ID);
        if (!idList.isEmpty()) {
          final String idStr = idList.get(idList.size() - 1).trim();
          changeKey = new Change.Key(idStr);
        } else {
          final ObjectId computedChangeId =
              ChangeIdUtil.computeChangeId(pullRequestCommit.getTree(),
                  pullRequestCommit, pullRequestCommit.getAuthorIdent(),
                  pullRequestCommit.getCommitterIdent(), pullRequestMesage);

          changeKey = new Change.Key("I" + computedChangeId.name());
        }

        List<ChangeData> destChanges =
            queryProvider.get().byBranchKey(
                new Branch.NameKey(project.getNameKey(), destRef.getName()),
                changeKey);

        if (destChanges.size() > 1) {
          throw new InvalidChangeOperationException(
              "Multiple Changes with Change-ID "
                  + changeKey
                  + " already exist on the target branch: cannot add a new patch-set "
                  + destinationBranch);
        } else if (destChanges.size() == 1) {
          // The change key exists on the destination branch: adding a new
          // patch-set
          Change destChange = destChanges.get(0).change();

          ChangeControl changeControl =
              projectControlFactory.controlFor(project.getNameKey()).controlFor(
                  destChange).forUser(userFactory.create(pullRequestOwner));

          return insertPatchSet(git, revWalk, destChange, pullRequestCommit,
              changeControl, pullRequestOwner, pullRequestMesage, doValidation);
        } else {
          // Change key not found on destination branch. We can create a new
          // change.
          return (newChange =
              createNewChange(db, git, revWalk, changeKey,
                  project.getNameKey(), destRef, pullRequestOwner,
                  pullRequestCommit, refControl, pullRequestMesage, topic,
                  doValidation));
        }
      } finally {
        if (newChange == null) {
          db.rollback();
        }
      }
    } finally {
      git.close();
    }
  }

  private Change.Id insertPatchSet(Repository git, RevWalk revWalk,
      Change change, RevCommit cherryPickCommit, ChangeControl changeControl,
      Account.Id pullRequestOwnerId, String pullRequestMessage,
      boolean doValidation) throws InvalidChangeOperationException,
      IOException, OrmException, NoSuchChangeException {
    PatchSetInserter patchSetInserter =
        patchSetInserterFactory.create(git, revWalk, changeControl, cherryPickCommit);
    // This apparently useless method call is made for triggering
    // the creation of patchSet inside PatchSetInserter and thus avoiding a NPE
    patchSetInserter.getPatchSetId();
    patchSetInserter.setMessage(pullRequestMessage);

    patchSetInserter.setValidatePolicy(doValidation ? ValidatePolicy.GERRIT
        : ValidatePolicy.NONE);
    patchSetInserter.insert();
    return change.getId();
  }

  private Change.Id createNewChange(ReviewDb db, Repository git,
      RevWalk revWalk, Change.Key changeKey, Project.NameKey project,
      Ref destRef, Account.Id pullRequestOwner, RevCommit pullRequestCommit,
      RefControl refControl, String pullRequestMessage, String topic,
      boolean doValidation) throws OrmException,
      InvalidChangeOperationException, IOException {
    Change change =
        new Change(changeKey, new Change.Id(db.nextChangeId()),
            pullRequestOwner, new Branch.NameKey(project, destRef.getName()),
            TimeUtil.nowTs());
    if (topic != null) {
      change.setTopic(topic);
    }
    ChangeInserter ins = changeInserterFactory.create(
        refControl.getProjectControl(), change, pullRequestCommit);
    PatchSet newPatchSet = ins.getPatchSet();

    if (doValidation) {
      validate(git, pullRequestCommit, refControl, newPatchSet);
    }

    final RefUpdate ru = git.updateRef(newPatchSet.getRefName());
    ru.setExpectedOldObjectId(ObjectId.zeroId());
    ru.setNewObjectId(pullRequestCommit);
    ru.disableRefLog();
    if (ru.update(revWalk) != RefUpdate.Result.NEW) {
      throw new IOException(String.format("Failed to create ref %s in %s: %s",
          newPatchSet.getRefName(), change.getDest().getParentKey().get(),
          ru.getResult()));
    }

    ins.setMessage(
        buildChangeMessage(db, change, newPatchSet, pullRequestOwner, pullRequestMessage))
        .insert();

    return change.getId();
  }

  private void validate(Repository git, RevCommit pullRequestCommit,
      RefControl refControl, PatchSet newPatchSet)
      throws InvalidChangeOperationException {
    CommitValidators commitValidators =
        commitValidatorsFactory.create(refControl, new NoSshInfo(), git);
    CommitReceivedEvent commitReceivedEvent =
        new CommitReceivedEvent(new ReceiveCommand(ObjectId.zeroId(),
            pullRequestCommit.getId(), newPatchSet.getRefName()), refControl
            .getProjectControl().getProject(), refControl.getRefName(),
            pullRequestCommit, currentUser);

    try {
      commitValidators.validateForGerritCommits(commitReceivedEvent);
    } catch (CommitValidationException e) {
      throw new InvalidChangeOperationException(e.getMessage());
    }
  }

  private ChangeMessage buildChangeMessage(ReviewDb db, Change dest,
      PatchSet newPatchSet, Account.Id pullRequestAuthorId,
      String pullRequestMessage) throws OrmException {
    ChangeMessage cmsg =
        new ChangeMessage(new ChangeMessage.Key(dest.getId(),
            ChangeUtil.messageUUID(db)), pullRequestAuthorId, TimeUtil.nowTs(),
            newPatchSet.getId());
    cmsg.setMessage(pullRequestMessage);
    return cmsg;
  }
}
