// Copyright (C) 2009 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.httpd.rpc.project;

import com.google.gerrit.common.ChangeHookRunner;
import com.google.gerrit.httpd.rpc.Handler;
import com.google.gerrit.reviewdb.Branch;
import com.google.gerrit.reviewdb.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ReplicationQueue;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

class DeleteBranches extends Handler<Set<Branch.NameKey>> {
  private static final Logger log =
      LoggerFactory.getLogger(DeleteBranches.class);

  interface Factory {
    DeleteBranches create(@Assisted Project.NameKey name,
        @Assisted Set<Branch.NameKey> toRemove);
  }

  private final ProjectControl.Factory projectControlFactory;
  private final GitRepositoryManager repoManager;
  private final ReplicationQueue replication;
  private final IdentifiedUser identifiedUser;
  private final ChangeHookRunner hooks;

  private final Project.NameKey projectName;
  private final Set<Branch.NameKey> toRemove;

  @Inject
  DeleteBranches(final ProjectControl.Factory projectControlFactory,
      final GitRepositoryManager repoManager,
      final ReplicationQueue replication,
      final IdentifiedUser identifiedUser,
      final ChangeHookRunner hooks,

      @Assisted Project.NameKey name, @Assisted Set<Branch.NameKey> toRemove) {
    this.projectControlFactory = projectControlFactory;
    this.repoManager = repoManager;
    this.replication = replication;
    this.identifiedUser = identifiedUser;
    this.hooks = hooks;

    this.projectName = name;
    this.toRemove = toRemove;
  }

  @Override
  public Set<Branch.NameKey> call() throws NoSuchProjectException,
      RepositoryNotFoundException {
    final ProjectControl projectControl =
        projectControlFactory.controlFor(projectName);

    for (Branch.NameKey k : toRemove) {
      if (!projectName.equals(k.getParentKey())) {
        throw new IllegalArgumentException("All keys must be from same project");
      }
      if (!projectControl.controlForRef(k).canDelete()) {
        throw new IllegalStateException("Cannot delete " + k.getShortName());
      }
    }

    final Set<Branch.NameKey> deleted = new HashSet<Branch.NameKey>();
    final Repository r = repoManager.openRepository(projectName);
    try {
      for (final Branch.NameKey branchKey : toRemove) {
        final String refname = branchKey.get();
        final RefUpdate.Result result;
        final RefUpdate u;
        try {
          u = r.updateRef(refname);
          u.setForceUpdate(true);
          result = u.delete();
        } catch (IOException e) {
          log.error("Cannot delete " + branchKey, e);
          continue;
        }

        switch (result) {
          case NEW:
          case NO_CHANGE:
          case FAST_FORWARD:
          case FORCED:
            deleted.add(branchKey);
            replication.scheduleUpdate(projectName, refname);
            hooks.doRefUpdatedHook(branchKey, u, identifiedUser.getAccount());
            break;

          case REJECTED_CURRENT_BRANCH:
            log.warn("Cannot delete " + branchKey + ": " + result.name());
            break;

          default:
            log.error("Cannot delete " + branchKey + ": " + result.name());
            break;
        }
      }
    } finally {
      r.close();
    }
    return deleted;
  }
}
