<commit_before>package io.scalecube.services;

import static java.util.Objects.requireNonNull;

import io.scalecube.net.Address;
import io.scalecube.services.api.ErrorData;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.exceptions.ServiceClientErrorMapper;
import io.scalecube.services.exceptions.ServiceUnavailableException;
import io.scalecube.services.methods.MethodInfo;
import io.scalecube.services.methods.ServiceMethodInvoker;
import io.scalecube.services.methods.ServiceMethodRegistry;
import io.scalecube.services.registry.api.ServiceRegistry;
import io.scalecube.services.routing.Router;
import io.scalecube.services.routing.Routers;
import io.scalecube.services.transport.api.ClientTransport;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class ServiceCall {

  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCall.class);

  private static final ServiceMessage UNEXPECTED_EMPTY_RESPONSE =
      ServiceMessage.error(503, 503, "Unexpected empty response");

  private final ClientTransport transport;
  private final ServiceMethodRegistry methodRegistry;
  private final ServiceRegistry serviceRegistry;

  private Router router;
  private ServiceClientErrorMapper errorMapper;
  private Map<String, String> credentials = Collections.emptyMap();
  private String contentType;

  ServiceCall(
      ClientTransport transport,
      ServiceMethodRegistry methodRegistry,
      ServiceRegistry serviceRegistry) {
    this.transport = transport;
    this.methodRegistry = methodRegistry;
    this.serviceRegistry = serviceRegistry;
  }

  private ServiceCall(ServiceCall other) {
    this.transport = other.transport;
    this.methodRegistry = other.methodRegistry;
    this.serviceRegistry = other.serviceRegistry;
    // Set resettable fields
    this.router = other.router;
    this.errorMapper = other.errorMapper;
    this.contentType = other.contentType;
    this.credentials = Collections.unmodifiableMap(new HashMap<>(other.credentials));
  }

  /**
   * Creates new {@link ServiceCall}'s definition with a given router.
   *
   * @param routerType given class of the router.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall router(Class<? extends Router> routerType) {
    ServiceCall target = new ServiceCall(this);
    target.router = Routers.getRouter(routerType);
    return target;
  }

  /**
   * Creates new {@link ServiceCall}'s definition with a given router.
   *
   * @param router given.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall router(Router router) {
    ServiceCall target = new ServiceCall(this);
    target.router = router;
    return target;
  }

  /**
   * Creates new {@link ServiceCall}'s definition with a given error mapper.
   *
   * @param errorMapper given.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall errorMapper(ServiceClientErrorMapper errorMapper) {
    ServiceCall target = new ServiceCall(this);
    target.errorMapper = errorMapper;
    return target;
  }

  /**
   * Creates new {@link ServiceCall}'s definition with a given credentials.
   *
   * @param credentials given.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall credentials(Map<String, String> credentials) {
    ServiceCall target = new ServiceCall(this);
    target.credentials = Collections.unmodifiableMap(new HashMap<>(credentials));
    return target;
  }

  /**
   * Creates new {@link ServiceCall}'s definition with a given content type.
   *
   * @param contentType content type.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall contentType(String contentType) {
    ServiceCall target = new ServiceCall(this);
    target.contentType = contentType;
    return target;
  }

  /**<commit_msg>Mobing back ServiceCall; thinking how to get rid of credentials<commit_after>package io.scalecube.services;

import static java.util.Objects.requireNonNull;

import io.scalecube.net.Address;
import io.scalecube.services.api.ErrorData;
import io.scalecube.services.api.ServiceMessage;
import io.scalecube.services.exceptions.DefaultErrorMapper;
import io.scalecube.services.exceptions.ServiceClientErrorMapper;
import io.scalecube.services.exceptions.ServiceUnavailableException;
import io.scalecube.services.methods.MethodInfo;
import io.scalecube.services.methods.ServiceMethodInvoker;
import io.scalecube.services.methods.ServiceMethodRegistry;
import io.scalecube.services.registry.api.ServiceRegistry;
import io.scalecube.services.routing.Router;
import io.scalecube.services.routing.Routers;
import io.scalecube.services.transport.api.ClientTransport;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

public class ServiceCall {

  private static final Logger LOGGER = LoggerFactory.getLogger(ServiceCall.class);

  private static final ServiceMessage UNEXPECTED_EMPTY_RESPONSE =
      ServiceMessage.error(503, 503, "Unexpected empty response");

  private ClientTransport transport;
  private ServiceMethodRegistry methodRegistry;
  private ServiceRegistry serviceRegistry;
  private Router router;
  private ServiceClientErrorMapper errorMapper = DefaultErrorMapper.INSTANCE;
  private String contentType;

  public ServiceCall() {}

  private ServiceCall(ServiceCall other) {
    this.transport = other.transport;
    this.methodRegistry = other.methodRegistry;
    this.serviceRegistry = other.serviceRegistry;
    this.router = other.router;
    this.errorMapper = other.errorMapper;
    this.contentType = other.contentType;
  }

  /**
   * Setter for {@code clientTransport}.
   *
   * @param clientTransport client transport.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall transport(ClientTransport clientTransport) {
    ServiceCall target = new ServiceCall(this);
    target.transport = clientTransport;
    return target;
  }

  /**
   * Setter for {@code serviceRegistry}.
   *
   * @param serviceRegistry service registry.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall serviceRegistry(ServiceRegistry serviceRegistry) {
    ServiceCall target = new ServiceCall(this);
    target.serviceRegistry = serviceRegistry;
    return target;
  }

  /**
   * Setter for {@code methodRegistry}.
   *
   * @param methodRegistry method registry.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall methodRegistry(ServiceMethodRegistry methodRegistry) {
    ServiceCall target = new ServiceCall(this);
    target.methodRegistry = methodRegistry;
    return target;
  }

  /**
   * Setter for {@code routerType}.
   *
   * @param routerType method registry.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall router(Class<? extends Router> routerType) {
    ServiceCall target = new ServiceCall(this);
    target.router = Routers.getRouter(routerType);
    return target;
  }

  /**
   * Setter for {@code router}.
   *
   * @param router router.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall router(Router router) {
    ServiceCall target = new ServiceCall(this);
    target.router = router;
    return target;
  }

  /**
   * Setter for {@code errorMapper}.
   *
   * @param errorMapper error mapper.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall errorMapper(ServiceClientErrorMapper errorMapper) {
    ServiceCall target = new ServiceCall(this);
    target.errorMapper = errorMapper;
    return target;
  }

  /**
   * Setter for {@code contentType}.
   *
   * @param contentType content type.
   * @return new {@link ServiceCall} instance.
   */
  public ServiceCall contentType(String contentType) {
    ServiceCall target = new ServiceCall(this);
    target.contentType = contentType;
    return target;
  }

  /**
{'fraction_non_alphanumeric': 0.09377890841813136, 'fraction_numerical': 0.0018501387604070306, 'mean_word_length': 4.312653562653563, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7059366', 'n_tokens_mistral': 2421, 'n_tokens_neox': 2389, 'n_words': 595}