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

import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.config.TrackingFooters;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;

import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.FooterLine;
import org.eclipse.jgit.revwalk.RevCommit;

import java.util.Collections;
import java.util.List;
import java.util.Set;

public class ChangeInserter {
  private final GitReferenceUpdated gitRefUpdated;
  private final ChangeHooks hooks;
  private final ApprovalsUtil approvalsUtil;
  private final TrackingFooters trackingFooters;

  @Inject
  public ChangeInserter(final GitReferenceUpdated gitRefUpdated,
      ChangeHooks hooks, ApprovalsUtil approvalsUtil,
      TrackingFooters trackingFooters) {
    this.gitRefUpdated = gitRefUpdated;
    this.hooks = hooks;
    this.approvalsUtil = approvalsUtil;
    this.trackingFooters = trackingFooters;
  }

  public void insertChange(ReviewDb db, Change change, PatchSet ps,
      RevCommit commit, LabelTypes labelTypes, List<FooterLine> footerLines,
      PatchSetInfo info, Set<Account.Id> reviewers) throws OrmException {

    db.changes().beginTransaction(change.getId());
    try {
      ChangeUtil.insertAncestors(db, ps.getId(), commit);
      db.patchSets().insert(Collections.singleton(ps));
      db.changes().insert(Collections.singleton(change));
      ChangeUtil.updateTrackingIds(db, change, trackingFooters, footerLines);
      approvalsUtil.addReviewers(db, labelTypes, change, ps, info, reviewers,
          Collections.<Account.Id> emptySet());
      db.commit();
    } finally {
      db.rollback();
    }

    gitRefUpdated.fire(change.getProject(), ps.getRefName(), ObjectId.zeroId(),
        commit);
    hooks.doPatchsetCreatedHook(change, ps, db);
  }
}

@@ -837,16 +837,72 @@
 Change;%0A
+import com.google.gerrit.reviewdb.client.ChangeMessage;%0A
 import c
@@ -2302,16 +2302,365 @@
 eption %7B
+%0A    insertChange(db, change, null, ps, commit, labelTypes, footerLines, info, reviewers);%0A  %7D%0A%0A  public void insertChange(ReviewDb db, Change change,%0A      ChangeMessage changeMessage, PatchSet ps, RevCommit commit,%0A      LabelTypes labelTypes, List%3CFooterLine%3E footerLines, PatchSetInfo info,%0A      Set%3CAccount.Id%3E reviewers) throws OrmException %7B
 %0A%0A    db
@@ -3086,24 +3086,141 @@
 mptySet());%0A
+      if (changeMessage != null) %7B%0A        db.changeMessages().insert(Collections.singleton(changeMessage));%0A      %7D%0A
       db.com

Allow changeInserter to insert ChangeMessages