@Override
  @Transactional(readOnly = false)
  public Collection startFetcher(FetcherRequestDTO fetcherRequest, Collection collection) {
    try {
      /** Rest call to Fetcher */
      Client client = ClientBuilder.newBuilder().register(JacksonFeature.class).build();

      if (CollectionType.Twitter.equals(collection.getProvider())
          || CollectionType.Facebook.equals(collection.getProvider())) {
        WebTarget webResource =
            client.target(
                fetchMainUrl + "/" + collection.getProvider().toString().toLowerCase() + "/start");

        ObjectMapper objectMapper = JacksonWrapper.getObjectMapper();

        Response clientResponse =
            webResource
                .request(MediaType.APPLICATION_JSON)
                .post(Entity.json(objectMapper.writeValueAsString(fetcherRequest)), Response.class);

        // logger.info("ObjectMapper: " + objectMapper.writeValueAsString(fetcherRequest));
        String jsonString = clientResponse.readEntity(String.class);
        JSONParser parser = new JSONParser();
        JSONObject jsonResponse = (JSONObject) parser.parse(jsonString);
        // logger.info("NEW STRING: " + jsonResponse);
        FetcheResponseDTO response =
            objectMapper.readValue(jsonResponse.get("entity").toString(), FetcheResponseDTO.class);
        logger.info("start Response from fetchMain " + objectMapper.writeValueAsString(response));
        collection.setStatus(CollectionStatus.getByStatus(response.getStatusCode()));
      } else if (CollectionType.SMS.equals(collection.getProvider())) {
        WebTarget webResource =
            client.target(
                fetchMainUrl
                    + "/sms/start?collection_code="
                    + URLEncoder.encode(collection.getCode(), "UTF-8"));
        Response response = webResource.request(MediaType.APPLICATION_JSON).get();
        if (response.getStatus() == 200) collection.setStatus(CollectionStatus.INITIALIZING);
      }
      /** Update Status To database */
      collectionRepository.update(collection);
      return collection;
    } catch (Exception e) {
      logger.error("Error while starting Remote FetchMain Collection", e);
    }
    return null;
  }
  private Collection adaptCollectionDetailsInfoToCollection(
      CollectionDetailsInfo collectionInfo, UserAccount user) {

    Collection collection = new Collection();
    collection.setDurationHours(collectionInfo.getDurationHours());
    collection.setCode(collectionInfo.getCode());
    collection.setName(collectionInfo.getName());
    collection.setClassifierEnabled(false);
    collection.setProvider(CollectionType.valueOf(collectionInfo.getProvider()));
    collection.setOwner(user);
    collection.setStatus(CollectionStatus.NOT_RUNNING);
    collection.setPubliclyListed(true); // TODO: change default behavior to user choice

    collection.setGeoR(collectionInfo.getGeoR());
    collection.setGeo(collectionInfo.getGeo());
    collection.setTrack(collectionInfo.getTrack());
    collection.setCrisisType(crisisTypeService.getById(collectionInfo.getCrisisType()));
    collection.setFollow(collectionInfo.getFollow());
    collection.setLangFilters(collectionInfo.getLangFilters());
    collection.setMicromappersEnabled(Boolean.FALSE);
    collection.setProvider(CollectionType.valueOf(collectionInfo.getProvider()));
    collection.setPurpose(collectionInfo.getPurpose());
    collection.setFetchInterval(collectionInfo.getFetchInterval());
    collection.setFetchFrom(collectionInfo.getFetchFrom());

    if (CollectionType.SMS.equals(collectionInfo.getProvider())) {
      collection.setTrack(null);
      collection.setLangFilters(null);
      collection.setGeo(null);
      collection.setFollow(null);
    }

    Timestamp now = new Timestamp(System.currentTimeMillis());
    collection.setCreatedAt(now);
    collection.setUpdatedAt(now);
    return collection;
  }
  private Collection updateStatusCollection(
      String jsonResponse, Collection collection, Long accountId) throws Exception {
    ObjectMapper objectMapper = JacksonWrapper.getObjectMapper();
    FetcheResponseDTO response = objectMapper.readValue(jsonResponse, FetcheResponseDTO.class);
    if (response != null) {
      // MEGHNA: moved setting collection count to top of the method
      // to avoid individual status blocks setting collection count below
      if (response.getCollectionCount() != null
          && !response.getCollectionCount().equals(collection.getCount())) {
        collection.setCount(response.getCollectionCount());
        String lastDocument = response.getLastDocument();
        collection.setLastExecutionTime(response.getLastExecutionTime());
        if (lastDocument != null) collection.setLastDocument(lastDocument);
        collectionRepository.update(collection);
      }
      collection.setSourceOutage(response.isSourceOutage());
      if (!CollectionStatus.getByStatus(response.getStatusCode()).equals(collection.getStatus())) {

        CollectionStatus prevStatus = collection.getStatus();
        collection.setStatus(CollectionStatus.getByStatus(response.getStatusCode()));

        switch (CollectionStatus.getByStatus(response.getStatusCode())) {
          case NOT_FOUND:
            // case STOPPED:
            collection.setStatus(CollectionStatus.NOT_RUNNING);

            // Add collectionCount in collectionLog if it was not recorded.
            if (collection.getStartDate() != null
                && ((collection.getEndDate() != null
                        && collection.getStartDate().after(collection.getEndDate()))
                    || collection.getEndDate() == null)) {
              if (collectionLogRepository.countLogsStartedInInterval(
                      collection.getId(), collection.getStartDate(), new Date())
                  == 0) {
                CollectionLog collectionLog = new CollectionLog(collection);
                collectionLog.setEndDate(new Date());
                collectionLog.setUpdatedBy(accountId);
                collectionLogRepository.save(collectionLog);
              }
            }
          case RUNNING_WARNING:
            if (prevStatus == CollectionStatus.INITIALIZING) {
              collection = collectionRepository.start(collection.getId());
              break;
            }
          case WARNING:
            collectionRepository.update(collection);
            break;
          case RUNNING:
            collection = collectionRepository.start(collection.getId());
            break;
          case FATAL_ERROR:
            // collection = collectionRepository.stop(collection.getId());
            logger.warn("Fatal error, stopping collection " + collection.getId());
            if (prevStatus != CollectionStatus.FATAL_ERROR
                || prevStatus != CollectionStatus.NOT_RUNNING
                || prevStatus != CollectionStatus.STOPPED)
              this.stopFatalError(collection.getId(), accountId);
            break;
          case EXCEPTION:
            logger.warn(
                "Rejected Thread Execution Exception, restarting collection " + collection.getId());
            if (prevStatus != CollectionStatus.EXCEPTION) {
              this.stopFatalError(collection.getId(), accountId);
              this.start(collection.getId());
            }
            break;
          default:
            break;
        }
      }
    }
    return collection;
  }