// Path: src/main/java/mirror/tasks/TaskFactory.java
// public interface TaskFactory {
// 
//   default TaskHandle runTask(TaskLogic logic) {
//     return runTask(logic, null);
//   }
// 
//   TaskHandle runTask(TaskLogic logic, Runnable onFailure);
// 
//   void stopTask(TaskLogic logic);
// 
//   default TaskPool newTaskPool() {
//     return new TaskPool(this);
//   }
// 
// }


import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCall.Listener;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.stub.CallStreamObserver;
import io.grpc.stub.StreamObserver;
import mirror.MirrorGrpc.MirrorImplBase;
import mirror.tasks.TaskFactory;
package mirror;





/**
 * Listens for incoming clients and sets up {@link MirrorSession}s.
 *
 * In theory we can juggle multiple sessions, potentially even to the same destination
 * path, and things should just work (the sessions won't communicate directly, but instead
 * will see each other's file writes just like any other writer).
 */
public class MirrorServer extends MirrorImplBase {

  /**
   * Currently grpc-java doesn't return compressed responses, even if the client
   * has sent a compressed payload. This turns on gzip compression for all responses.
   */
  public static class EnableCompressionInterceptor implements ServerInterceptor {
    @Override
    public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
      call.setCompression("gzip");
      return next.startCall(call, headers);
    }
  }

  private static final Logger log = LoggerFactory.getLogger(MirrorServer.class);
  private final Map<String, MirrorSession> sessions = new HashMap<>();
// Path: src/main/java/mirror/tasks/TaskFactory.java
// public interface TaskFactory {
// 
//   default TaskHandle runTask(TaskLogic logic) {
//     return runTask(logic, null);
//   }
// 
//   TaskHandle runTask(TaskLogic logic, Runnable onFailure);
// 
//   void stopTask(TaskLogic logic);
// 
//   default TaskPool newTaskPool() {
//     return new TaskPool(this);
//   }
// 
// }


// Path: src/main/java/mirror/MirrorServer.java
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.annotations.VisibleForTesting;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCall.Listener;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.stub.CallStreamObserver;
import io.grpc.stub.StreamObserver;
import mirror.MirrorGrpc.MirrorImplBase;
import mirror.tasks.TaskFactory;

package mirror;





/**
 * Listens for incoming clients and sets up {@link MirrorSession}s.
 *
 * In theory we can juggle multiple sessions, potentially even to the same destination
 * path, and things should just work (the sessions won't communicate directly, but instead
 * will see each other's file writes just like any other writer).
 */
public class MirrorServer extends MirrorImplBase {

  /**
   * Currently grpc-java doesn't return compressed responses, even if the client
   * has sent a compressed payload. This turns on gzip compression for all responses.
   */
  public static class EnableCompressionInterceptor implements ServerInterceptor {
    @Override
    public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
      call.setCompression("gzip");
      return next.startCall(call, headers);
    }
  }

  private static final Logger log = LoggerFactory.getLogger(MirrorServer.class);
  private final Map<String, MirrorSession> sessions = new HashMap<>();
  private final TaskFactory taskFactory;