// 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.google.gerrit.server.git;

import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.notes.Note;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.notes.NoteMapMerger;
import org.eclipse.jgit.notes.NoteMerger;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;

import java.io.IOException;

/**
 * A utility class for updating a notes branch with automatic merge of note
 * trees.
 */
public class NotesBranchUtil {
  public interface Factory {
    NotesBranchUtil create(Project.NameKey project, Repository db,
        ObjectInserter inserter);
  }

  private static final int MAX_LOCK_FAILURE_CALLS = 10;
  private static final int SLEEP_ON_LOCK_FAILURE_MS = 25;

  private final PersonIdent gerritIdent;
  private final GitReferenceUpdated gitRefUpdated;
  private final Project.NameKey project;
  private final Repository db;
  private final ObjectInserter inserter;

  private RevCommit baseCommit;
  private NoteMap base;

  private RevCommit oursCommit;
  private NoteMap ours;

  private RevWalk revWalk;
  private ObjectReader reader;
  private boolean overwrite;

  private ReviewNoteMerger noteMerger;

  @Inject
  public NotesBranchUtil(@GerritPersonIdent final PersonIdent gerritIdent,
      final GitReferenceUpdated gitRefUpdated,
      @Assisted Project.NameKey project,
      @Assisted Repository db,
      @Assisted ObjectInserter inserter) {
    this.gerritIdent = gerritIdent;
    this.gitRefUpdated = gitRefUpdated;
    this.project = project;
    this.db = db;
    this.inserter = inserter;
  }

  /**
   * Create a new commit in the {@code notesBranch} by updating existing
   * or creating new notes from the {@code notes} map.
   *
   * @param notes map of notes
   * @param notesBranch notes branch to update
   * @param commitAuthor author of the commit in the notes branch
   * @param commitMessage for the commit in the notes branch
   * @throws IOException
   * @throws ConcurrentRefUpdateException
   */
  public final void commitAllNotes(NoteMap notes, String notesBranch,
      PersonIdent commitAuthor, String commitMessage) throws IOException,
      ConcurrentRefUpdateException {
    this.overwrite = true;
    commitNotes(notes, notesBranch, commitAuthor, commitMessage);
  }

  /**
   * Create a new commit in the {@code notesBranch} by creating not yet
   * existing notes from the {@code notes} map. The notes from the
   * {@code notes} map which already exist in the note-tree of the
   * tip of the {@code notesBranch} will not be updated.
   *
   * @param notes map of notes
   * @param notesBranch notes branch to update
   * @param commitAuthor author of the commit in the notes branch
   * @param commitMessage for the commit in the notes branch
   * @return map with those notes from the {@code notes} that were newly
   *         created
   * @throws IOException
   * @throws ConcurrentRefUpdateException
   */
  public final NoteMap commitNewNotes(NoteMap notes, String notesBranch,
      PersonIdent commitAuthor, String commitMessage) throws IOException,
      ConcurrentRefUpdateException {
    this.overwrite = false;
    commitNotes(notes, notesBranch, commitAuthor, commitMessage);
    NoteMap newlyCreated = NoteMap.newEmptyMap();
    for (Note n : notes) {
      if (base == null || !base.contains(n)) {
        newlyCreated.set(n, n.getData());
      }
    }
    return newlyCreated;
  }

  private void commitNotes(NoteMap notes, String notesBranch,
      PersonIdent commitAuthor, String commitMessage) throws IOException,
      ConcurrentRefUpdateException {
    try {
      revWalk = new RevWalk(db);
      reader = db.newObjectReader();
      loadBase(notesBranch);
      if (overwrite) {
        addAllNotes(notes);
      } else {
        addNewNotes(notes);
      }
      if (base != null) {
        oursCommit = createCommit(ours, commitAuthor, commitMessage, baseCommit);
      } else {
        oursCommit = createCommit(ours, commitAuthor, commitMessage);
      }
      updateRef(notesBranch);
    } finally {
      revWalk.close();
      reader.close();
    }
  }

  private void addNewNotes(NoteMap notes) throws IOException {
    for (Note n : notes) {
      if (! ours.contains(n)) {
        ours.set(n, n.getData());
      }
    }
  }

  private void addAllNotes(NoteMap notes) throws IOException {
    for (Note n : notes) {
      if (ours.contains(n)) {
        // Merge the existing and the new note as if they are both new,
        // means: base == null
        // There is no really a common ancestry for these two note revisions
        ObjectId noteContent = getNoteMerger().merge(null, n, ours.getNote(n),
            reader, inserter).getData();
        ours.set(n, noteContent);
      } else {
        ours.set(n, n.getData());
      }
    }
  }

  private NoteMerger getNoteMerger() {
    if (noteMerger == null) {
      noteMerger = new ReviewNoteMerger();
    }
    return noteMerger;
  }

  private void loadBase(String notesBranch) throws IOException {
    Ref branch = db.getRef(notesBranch);
    if (branch != null) {
      baseCommit = revWalk.parseCommit(branch.getObjectId());
      base = NoteMap.read(revWalk.getObjectReader(), baseCommit);
    }
    if (baseCommit != null) {
      ours = NoteMap.read(revWalk.getObjectReader(), baseCommit);
    } else {
      ours = NoteMap.newEmptyMap();
    }
  }

  private RevCommit createCommit(NoteMap map, PersonIdent author,
      String message, RevCommit... parents) throws IOException {
    CommitBuilder b = new CommitBuilder();
    b.setTreeId(map.writeTree(inserter));
    b.setAuthor(author != null ? author : gerritIdent);
    b.setCommitter(gerritIdent);
    if (parents.length > 0) {
      b.setParentIds(parents);
    }
    b.setMessage(message);
    ObjectId commitId = inserter.insert(b);
    inserter.flush();
    return revWalk.parseCommit(commitId);
  }

  private void updateRef(String notesBranch) throws IOException,
      MissingObjectException, IncorrectObjectTypeException,
      CorruptObjectException, ConcurrentRefUpdateException {
    if (baseCommit != null && oursCommit.getTree().equals(baseCommit.getTree())) {
      // If the trees are identical, there is no change in the notes.
      // Avoid saving this commit as it has no new information.
      return;
    }

    int remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;
    RefUpdate refUpdate = createRefUpdate(notesBranch, oursCommit, baseCommit);

    for (;;) {
      Result result = refUpdate.update();

      if (result == Result.LOCK_FAILURE) {
        if (--remainingLockFailureCalls > 0) {
          try {
            Thread.sleep(SLEEP_ON_LOCK_FAILURE_MS);
          } catch (InterruptedException e) {
            // ignore
          }
        } else {
          throw new ConcurrentRefUpdateException("Failed to lock the ref: "
              + notesBranch, db.getRef(notesBranch), result);
        }

      } else if (result == Result.REJECTED) {
        RevCommit theirsCommit =
            revWalk.parseCommit(refUpdate.getOldObjectId());
        NoteMap theirs =
            NoteMap.read(revWalk.getObjectReader(), theirsCommit);
        NoteMapMerger merger =
            new NoteMapMerger(db, getNoteMerger(), MergeStrategy.RESOLVE);
        NoteMap merged = merger.merge(base, ours, theirs);
        RevCommit mergeCommit =
            createCommit(merged, gerritIdent, "Merged note commits\n",
                theirsCommit, oursCommit);
        refUpdate = createRefUpdate(notesBranch, mergeCommit, theirsCommit);
        remainingLockFailureCalls = MAX_LOCK_FAILURE_CALLS;

      } else if (result == Result.IO_FAILURE) {
        throw new IOException("Couldn't update " + notesBranch + ". "
            + result.name());
      } else {
        gitRefUpdated.fire(project, refUpdate);
        break;
      }
    }
  }

  private RefUpdate createRefUpdate(String notesBranch, ObjectId newObjectId,
      ObjectId expectedOldObjectId) throws IOException {
    RefUpdate refUpdate = db.updateRef(notesBranch);
    refUpdate.setNewObjectId(newObjectId);
    if (expectedOldObjectId == null) {
      refUpdate.setExpectedOldObjectId(ObjectId.zeroId());
    } else {
      refUpdate.setExpectedOldObjectId(expectedOldObjectId);
    }
    return refUpdate;
  }
}
