// Path: src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
// static final NamedFluentLogger repLog = NamedFluentLogger.forName(REPLICATION_LOG_NAME);
// 
// Path: src/main/java/com/googlesource/gerrit/plugins/replication/events/ProjectDeletionState.java
// public class ProjectDeletionState {
//   public interface Factory {
//     ProjectDeletionState create(Project.NameKey project);
//   }
// 
//   private final DynamicItem<EventDispatcher> eventDispatcher;
//   private final Project.NameKey project;
//   private final ConcurrentMap<URIish, ProjectDeletionStatus> statusByURI =
//       new ConcurrentHashMap<>();
// 
//   @Inject
//   public ProjectDeletionState(
//       DynamicItem<EventDispatcher> eventDispatcher, @Assisted Project.NameKey project) {
//     this.eventDispatcher = eventDispatcher;
//     this.project = project;
//   }
// 
//   public void setToProcess(URIish uri) {
//     statusByURI.put(uri, TO_PROCESS);
//   }
// 
//   public void setScheduled(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, SCHEDULED, new ProjectDeletionReplicationScheduledEvent(project.get(), uri));
//   }
// 
//   public void setSucceeded(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, SUCCEEDED, new ProjectDeletionReplicationSucceededEvent(project.get(), uri));
//     notifyIfDeletionDoneOnAllNodes();
//   }
// 
//   public void setFailed(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, FAILED, new ProjectDeletionReplicationFailedEvent(project.get(), uri));
//     notifyIfDeletionDoneOnAllNodes();
//   }
// 
//   private void setStatusAndBroadcastEvent(
//       URIish uri, ProjectDeletionStatus status, ProjectEvent event) {
//     statusByURI.put(uri, status);
//     eventDispatcher.get().postEvent(project, event);
//   }
// 
//   public void notifyIfDeletionDoneOnAllNodes() {
//     synchronized (statusByURI) {
//       if (!statusByURI.isEmpty()
//           && statusByURI.values().stream()
//               .noneMatch(s -> s.equals(TO_PROCESS) || s.equals(SCHEDULED))) {
// 
//         statusByURI.clear();
//         eventDispatcher
//             .get()
//             .postEvent(project, new ProjectDeletionReplicationDoneEvent(project.get()));
//       }
//     }
//   }
// 
//   public enum ProjectDeletionStatus {
//     TO_PROCESS,
//     SCHEDULED,
//     FAILED,
//     SUCCEEDED;
//   }
// }


import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.server.ioutil.HexFormat;
import com.google.gerrit.server.util.IdGenerator;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.replication.events.ProjectDeletionState;
import java.util.Optional;
import org.eclipse.jgit.transport.URIish;
  private final URIish replicateURI;
  private final Project.NameKey project;
  private final ProjectDeletionState state;

  @Inject
  DeleteProjectTask(
      DynamicItem<AdminApiFactory> adminApiFactory,
      IdGenerator ig,
      @Assisted ProjectDeletionState state,
      @Assisted URIish replicateURI,
      @Assisted Project.NameKey project) {
    this.adminApiFactory = adminApiFactory;
    this.id = ig.next();
    this.replicateURI = replicateURI;
    this.project = project;
    this.state = state;
  }

  @Override
  public void run() {
    Optional<AdminApi> adminApi = adminApiFactory.get().create(replicateURI);
    if (adminApi.isPresent()) {
      if (adminApi.get().deleteProject(project)) {
        state.setSucceeded(replicateURI);
      } else {
        state.setFailed(replicateURI);
      }
      return;
    }

// Path: src/main/java/com/googlesource/gerrit/plugins/replication/ReplicationQueue.java
// static final NamedFluentLogger repLog = NamedFluentLogger.forName(REPLICATION_LOG_NAME);
// 
// Path: src/main/java/com/googlesource/gerrit/plugins/replication/events/ProjectDeletionState.java
// public class ProjectDeletionState {
//   public interface Factory {
//     ProjectDeletionState create(Project.NameKey project);
//   }
// 
//   private final DynamicItem<EventDispatcher> eventDispatcher;
//   private final Project.NameKey project;
//   private final ConcurrentMap<URIish, ProjectDeletionStatus> statusByURI =
//       new ConcurrentHashMap<>();
// 
//   @Inject
//   public ProjectDeletionState(
//       DynamicItem<EventDispatcher> eventDispatcher, @Assisted Project.NameKey project) {
//     this.eventDispatcher = eventDispatcher;
//     this.project = project;
//   }
// 
//   public void setToProcess(URIish uri) {
//     statusByURI.put(uri, TO_PROCESS);
//   }
// 
//   public void setScheduled(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, SCHEDULED, new ProjectDeletionReplicationScheduledEvent(project.get(), uri));
//   }
// 
//   public void setSucceeded(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, SUCCEEDED, new ProjectDeletionReplicationSucceededEvent(project.get(), uri));
//     notifyIfDeletionDoneOnAllNodes();
//   }
// 
//   public void setFailed(URIish uri) {
//     setStatusAndBroadcastEvent(
//         uri, FAILED, new ProjectDeletionReplicationFailedEvent(project.get(), uri));
//     notifyIfDeletionDoneOnAllNodes();
//   }
// 
//   private void setStatusAndBroadcastEvent(
//       URIish uri, ProjectDeletionStatus status, ProjectEvent event) {
//     statusByURI.put(uri, status);
//     eventDispatcher.get().postEvent(project, event);
//   }
// 
//   public void notifyIfDeletionDoneOnAllNodes() {
//     synchronized (statusByURI) {
//       if (!statusByURI.isEmpty()
//           && statusByURI.values().stream()
//               .noneMatch(s -> s.equals(TO_PROCESS) || s.equals(SCHEDULED))) {
// 
//         statusByURI.clear();
//         eventDispatcher
//             .get()
//             .postEvent(project, new ProjectDeletionReplicationDoneEvent(project.get()));
//       }
//     }
//   }
// 
//   public enum ProjectDeletionStatus {
//     TO_PROCESS,
//     SCHEDULED,
//     FAILED,
//     SUCCEEDED;
//   }
// }


// Path: src/main/java/com/googlesource/gerrit/plugins/replication/DeleteProjectTask.java
import static com.googlesource.gerrit.plugins.replication.ReplicationQueue.repLog;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.server.ioutil.HexFormat;
import com.google.gerrit.server.util.IdGenerator;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.replication.events.ProjectDeletionState;
import java.util.Optional;
import org.eclipse.jgit.transport.URIish;

  private final URIish replicateURI;
  private final Project.NameKey project;
  private final ProjectDeletionState state;

  @Inject
  DeleteProjectTask(
      DynamicItem<AdminApiFactory> adminApiFactory,
      IdGenerator ig,
      @Assisted ProjectDeletionState state,
      @Assisted URIish replicateURI,
      @Assisted Project.NameKey project) {
    this.adminApiFactory = adminApiFactory;
    this.id = ig.next();
    this.replicateURI = replicateURI;
    this.project = project;
    this.state = state;
  }

  @Override
  public void run() {
    Optional<AdminApi> adminApi = adminApiFactory.get().create(replicateURI);
    if (adminApi.isPresent()) {
      if (adminApi.get().deleteProject(project)) {
        state.setSucceeded(replicateURI);
      } else {
        state.setFailed(replicateURI);
      }
      return;
    }

    repLog.atWarning().log("Cannot delete project %s on remote site %s.", project, replicateURI);