// Copyright (C) 2011 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.meta;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Project;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.BatchRefUpdate;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;

/** Helps with the updating of a {@link VersionedMetaData}. */
public class MetaDataUpdate implements AutoCloseable {
  @Singleton
  public static class User {
    private final InternalFactory factory;
    private final GitRepositoryManager mgr;
    private final Provider<PersonIdent> serverIdentProvider;
    private final Provider<IdentifiedUser> identifiedUser;

    @Inject
    User(
        InternalFactory factory,
        GitRepositoryManager mgr,
        @GerritPersonIdent Provider<PersonIdent> serverIdentProvider,
        Provider<IdentifiedUser> identifiedUser) {
      this.factory = factory;
      this.mgr = mgr;
      this.serverIdentProvider = serverIdentProvider;
      this.identifiedUser = identifiedUser;
    }

    public PersonIdent getUserPersonIdent() {
      return createPersonIdent(identifiedUser.get());
    }

    public MetaDataUpdate create(Project.NameKey name)
        throws RepositoryNotFoundException, IOException {
      return create(name, identifiedUser.get());
    }

    public MetaDataUpdate create(Project.NameKey name, IdentifiedUser user)
        throws RepositoryNotFoundException, IOException {
      return create(name, user, null);
    }

    /**
     * Create an update using an existing batch ref update.
     *
     * <p>This allows batching together updates to multiple metadata refs. For making multiple
     * commits to a single metadata ref, see {@link VersionedMetaData#openUpdate(MetaDataUpdate)}.
     *
     * @param name project name.
     * @param user user for the update.
     * @param batch batch update to use; the caller is responsible for committing the update.
     */
    public MetaDataUpdate create(Project.NameKey name, IdentifiedUser user, BatchRefUpdate batch)
        throws RepositoryNotFoundException, IOException {
      Repository repo = mgr.openRepository(name);
      MetaDataUpdate md = create(name, repo, user, batch);
      md.setCloseRepository(true);
      return md;
    }

    /**
     * Create an update using an existing batch ref update.
     *
     * <p>This allows batching together updates to multiple metadata refs. For making multiple
     * commits to a single metadata ref, see {@link VersionedMetaData#openUpdate(MetaDataUpdate)}.
     *
     * <p>Important: Create a new MetaDataUpdate instance for each update:
     *
     * <pre>
     * <code>
     *   try (Repository repo = repoMgr.openRepository(allUsersName);
     *       RevWalk rw = new RevWalk(repo)) {
     *     BatchRefUpdate batchUpdate = repo.getRefDatabase().newBatchUpdate();
     *     // WRONG: create the MetaDataUpdate instance here and reuse it for
     *     //        all updates in the loop
     *     for{@code (Map.Entry<Account.Id, DiffPreferencesInfo> e : diffPrefsFromDb)} {
     *       // CORRECT: create a new MetaDataUpdate instance for each update
     *       try (MetaDataUpdate md =
     *           metaDataUpdateFactory.create(allUsersName, batchUpdate)) {
     *         md.setMessage("Import diff preferences from reviewdb\n");
     *         VersionedAccountPreferences vPrefs =
     *             VersionedAccountPreferences.forUser(e.getKey());
     *         storeSection(vPrefs.getConfig(), UserConfigSections.DIFF, null,
     *             e.getValue(), DiffPreferencesInfo.defaults());
     *         vPrefs.commit(md);
     *       } catch (ConfigInvalidException e) {
     *         // TODO handle exception
     *       }
     *     }
     *     batchUpdate.execute(rw, NullProgressMonitor.INSTANCE);
     *   }
     * </code>
     * </pre>
     *
     * @param name project name.
     * @param repository the repository to update; the caller is responsible for closing the
     *     repository.
     * @param user user for the update.
     * @param batch batch update to use; the caller is responsible for committing the update.
     */
    public MetaDataUpdate create(
        Project.NameKey name, Repository repository, IdentifiedUser user, BatchRefUpdate batch) {
      MetaDataUpdate md = factory.create(name, repository, batch);
      md.getCommitBuilder().setCommitter(serverIdentProvider.get());
      md.setAuthor(user);
      return md;
    }

    private PersonIdent createPersonIdent(IdentifiedUser user) {
      PersonIdent serverIdent = serverIdentProvider.get();
      return user.newCommitterIdent(serverIdent.getWhen(), serverIdent.getTimeZone());
    }
  }

  @Singleton
  public static class Server {
    private final InternalFactory factory;
    private final GitRepositoryManager mgr;
    private final Provider<PersonIdent> serverIdentProvider;

    @Inject
    Server(
        InternalFactory factory,
        GitRepositoryManager mgr,
        @GerritPersonIdent Provider<PersonIdent> serverIdentProvider) {
      this.factory = factory;
      this.mgr = mgr;
      this.serverIdentProvider = serverIdentProvider;
    }

    public MetaDataUpdate create(Project.NameKey name)
        throws RepositoryNotFoundException, IOException {
      return create(name, null);
    }

    /** See {@link User#create(Project.NameKey, IdentifiedUser, BatchRefUpdate)} */
    public MetaDataUpdate create(Project.NameKey name, BatchRefUpdate batch)
        throws RepositoryNotFoundException, IOException {
      Repository repo = mgr.openRepository(name);
      MetaDataUpdate md = factory.create(name, repo, batch);
      md.setCloseRepository(true);
      PersonIdent serverIdent = serverIdentProvider.get();
      md.getCommitBuilder().setAuthor(serverIdent);
      md.getCommitBuilder().setCommitter(serverIdent);
      return md;
    }
  }

  public interface InternalFactory {
    MetaDataUpdate create(
        @Assisted Project.NameKey projectName,
        @Assisted Repository repository,
        @Assisted @Nullable BatchRefUpdate batch);
  }

  private final GitReferenceUpdated gitRefUpdated;
  private final Project.NameKey projectName;
  private final Repository repository;
  private final BatchRefUpdate batch;
  private final CommitBuilder commit;
  private boolean allowEmpty;
  private boolean insertChangeId;
  private boolean closeRepository;
  private IdentifiedUser author;

  @Inject
  public MetaDataUpdate(
      GitReferenceUpdated gitRefUpdated,
      @Assisted Project.NameKey projectName,
      @Assisted Repository repository,
      @Assisted @Nullable BatchRefUpdate batch) {
    this.gitRefUpdated = gitRefUpdated;
    this.projectName = projectName;
    this.repository = repository;
    this.batch = batch;
    this.commit = new CommitBuilder();
  }

  public MetaDataUpdate(
      GitReferenceUpdated gitRefUpdated, Project.NameKey projectName, Repository repository) {
    this(gitRefUpdated, projectName, repository, null);
  }

  /** Set the commit message used when committing the update. */
  public void setMessage(String message) {
    getCommitBuilder().setMessage(message);
  }

  public void setAuthor(IdentifiedUser author) {
    this.author = author;
    getCommitBuilder()
        .setAuthor(
            author.newCommitterIdent(
                getCommitBuilder().getCommitter().getWhen(),
                getCommitBuilder().getCommitter().getTimeZone()));
  }

  public void setAllowEmpty(boolean allowEmpty) {
    this.allowEmpty = allowEmpty;
  }

  public void setInsertChangeId(boolean insertChangeId) {
    this.insertChangeId = insertChangeId;
  }

  public void setCloseRepository(boolean closeRepository) {
    this.closeRepository = closeRepository;
  }

  /** Returns batch in which to run the update, or {@code null} for no batch. */
  BatchRefUpdate getBatch() {
    return batch;
  }

  /** Close the cached Repository handle. */
  @Override
  public void close() {
    if (closeRepository) {
      getRepository().close();
    }
  }

  public Project.NameKey getProjectName() {
    return projectName;
  }

  public Repository getRepository() {
    return repository;
  }

  boolean allowEmpty() {
    return allowEmpty;
  }

  boolean insertChangeId() {
    return insertChangeId;
  }

  public CommitBuilder getCommitBuilder() {
    return commit;
  }

  protected void fireGitRefUpdatedEvent(RefUpdate ru) {
    gitRefUpdated.fire(projectName, ru, author == null ? null : author.state());
  }
}
