// Path: src/main/java/com/googlesource/gerrit/plugins/replication/PushResultProcessing.java
// public static class CommandProcessing implements PushResultProcessing {
//   private WeakReference<StartCommand> sshCommand;
//   private AtomicBoolean hasError = new AtomicBoolean();
// 
//   CommandProcessing(StartCommand sshCommand) {
//     this.sshCommand = new WeakReference<>(sshCommand);
//   }
// 
//   @Override
//   public void onRefReplicatedToOneNode(
//       String project,
//       String ref,
//       URIish uri,
//       RefPushResult status,
//       RemoteRefUpdate.Status refStatus) {
//     StringBuilder sb = new StringBuilder();
//     sb.append("Replicate ");
//     sb.append(project);
//     sb.append(" ref ");
//     sb.append(ref);
//     sb.append(" to ");
//     sb.append(resolveNodeName(uri));
//     sb.append(", ");
//     switch (status) {
//       case SUCCEEDED:
//         sb.append("Succeeded!");
//         break;
//       case FAILED:
//         sb.append("FAILED!");
//         hasError.compareAndSet(false, true);
//         break;
//       case NOT_ATTEMPTED:
//         sb.append("NOT ATTEMPTED!");
//         break;
//       default:
//         sb.append("UNKNOWN RESULT!");
//         break;
//     }
//     sb.append(" (");
//     sb.append(refStatus == null ? "unknown" : refStatus.toString());
//     sb.append(")");
//     writeStdOut(sb.toString());
//   }
// 
//   @Override
//   public void onRefReplicatedToAllNodes(String project, String ref, int nodesCount) {
//     StringBuilder sb = new StringBuilder();
//     sb.append("Replication of ");
//     sb.append(project);
//     sb.append(" ref ");
//     sb.append(ref);
//     sb.append(" completed to ");
//     sb.append(nodesCount);
//     sb.append(" nodes, ");
//     writeStdOut(sb.toString());
//   }
// 
//   @Override
//   public void onAllRefsReplicatedToAllNodes(int totalPushTasksCount) {
//     if (totalPushTasksCount == 0) {
//       return;
//     }
//     writeStdOut("----------------------------------------------");
//     if (hasError.get()) {
//       writeStdOut("Replication completed with some errors!");
//     } else {
//       writeStdOut("Replication completed successfully!");
//     }
//   }
// 
//   @Override
//   public void writeStdOut(String message) {
//     StartCommand command = sshCommand.get();
//     if (command != null) {
//       command.writeStdOutSync(message);
//     }
//   }
// 
//   @Override
//   public void writeStdErr(String message) {
//     StartCommand command = sshCommand.get();
//     if (command != null) {
//       command.writeStdErrSync(message);
//     }
//   }
// }


import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.PushResultProcessing.CommandProcessing;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
// 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.googlesource.gerrit.plugins.replication;


@RequiresCapability(StartReplicationCapability.START_REPLICATION)
@CommandMetaData(
    name = "start",
    description = "Start replication for specific project or all projects")
final class StartCommand extends SshCommand {
  @Inject private ReplicationStateLogger stateLog;

  @Option(name = "--all", usage = "push all known projects")
  private boolean all;

  @Option(name = "--url", metaVar = "PATTERN", usage = "pattern to match URL on")
  private String urlMatch;

  @Option(name = "--wait", usage = "wait for replication to finish before exiting")
  private boolean wait;

  @Option(name = "--now", usage = "start replication without waiting for replicationDelay")
  private boolean now;

  @Argument(index = 0, multiValued = true, metaVar = "PATTERN", usage = "project name pattern")
  private List<String> projectPatterns = new ArrayList<>(2);

  @Inject private PushAll.Factory pushFactory;

  private final Object lock = new Object();

  @Override
  protected void run() throws Failure {
    if (all && !projectPatterns.isEmpty()) {
      throw new UnloggedFailure(1, "error: cannot combine --all and PROJECT");
    }

// Path: src/main/java/com/googlesource/gerrit/plugins/replication/PushResultProcessing.java
// public static class CommandProcessing implements PushResultProcessing {
//   private WeakReference<StartCommand> sshCommand;
//   private AtomicBoolean hasError = new AtomicBoolean();
// 
//   CommandProcessing(StartCommand sshCommand) {
//     this.sshCommand = new WeakReference<>(sshCommand);
//   }
// 
//   @Override
//   public void onRefReplicatedToOneNode(
//       String project,
//       String ref,
//       URIish uri,
//       RefPushResult status,
//       RemoteRefUpdate.Status refStatus) {
//     StringBuilder sb = new StringBuilder();
//     sb.append("Replicate ");
//     sb.append(project);
//     sb.append(" ref ");
//     sb.append(ref);
//     sb.append(" to ");
//     sb.append(resolveNodeName(uri));
//     sb.append(", ");
//     switch (status) {
//       case SUCCEEDED:
//         sb.append("Succeeded!");
//         break;
//       case FAILED:
//         sb.append("FAILED!");
//         hasError.compareAndSet(false, true);
//         break;
//       case NOT_ATTEMPTED:
//         sb.append("NOT ATTEMPTED!");
//         break;
//       default:
//         sb.append("UNKNOWN RESULT!");
//         break;
//     }
//     sb.append(" (");
//     sb.append(refStatus == null ? "unknown" : refStatus.toString());
//     sb.append(")");
//     writeStdOut(sb.toString());
//   }
// 
//   @Override
//   public void onRefReplicatedToAllNodes(String project, String ref, int nodesCount) {
//     StringBuilder sb = new StringBuilder();
//     sb.append("Replication of ");
//     sb.append(project);
//     sb.append(" ref ");
//     sb.append(ref);
//     sb.append(" completed to ");
//     sb.append(nodesCount);
//     sb.append(" nodes, ");
//     writeStdOut(sb.toString());
//   }
// 
//   @Override
//   public void onAllRefsReplicatedToAllNodes(int totalPushTasksCount) {
//     if (totalPushTasksCount == 0) {
//       return;
//     }
//     writeStdOut("----------------------------------------------");
//     if (hasError.get()) {
//       writeStdOut("Replication completed with some errors!");
//     } else {
//       writeStdOut("Replication completed successfully!");
//     }
//   }
// 
//   @Override
//   public void writeStdOut(String message) {
//     StartCommand command = sshCommand.get();
//     if (command != null) {
//       command.writeStdOutSync(message);
//     }
//   }
// 
//   @Override
//   public void writeStdErr(String message) {
//     StartCommand command = sshCommand.get();
//     if (command != null) {
//       command.writeStdErrSync(message);
//     }
//   }
// }


// Path: src/main/java/com/googlesource/gerrit/plugins/replication/StartCommand.java
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import com.googlesource.gerrit.plugins.replication.PushResultProcessing.CommandProcessing;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

// 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.googlesource.gerrit.plugins.replication;


@RequiresCapability(StartReplicationCapability.START_REPLICATION)
@CommandMetaData(
    name = "start",
    description = "Start replication for specific project or all projects")
final class StartCommand extends SshCommand {
  @Inject private ReplicationStateLogger stateLog;

  @Option(name = "--all", usage = "push all known projects")
  private boolean all;

  @Option(name = "--url", metaVar = "PATTERN", usage = "pattern to match URL on")
  private String urlMatch;

  @Option(name = "--wait", usage = "wait for replication to finish before exiting")
  private boolean wait;

  @Option(name = "--now", usage = "start replication without waiting for replicationDelay")
  private boolean now;

  @Argument(index = 0, multiValued = true, metaVar = "PATTERN", usage = "project name pattern")
  private List<String> projectPatterns = new ArrayList<>(2);

  @Inject private PushAll.Factory pushFactory;

  private final Object lock = new Object();

  @Override
  protected void run() throws Failure {
    if (all && !projectPatterns.isEmpty()) {
      throw new UnloggedFailure(1, "error: cannot combine --all and PROJECT");
    }

    ReplicationState state = new ReplicationState(new CommandProcessing(this));