package com.hubspot.baragon.managers;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.inject.Inject;
import com.hubspot.baragon.data.BaragonStateDatastore;
import com.hubspot.baragon.models.BaragonRequest;
import com.hubspot.baragon.models.BaragonResponse;
import com.hubspot.baragon.models.BaragonService;
import com.hubspot.baragon.models.BaragonServiceState;
import com.hubspot.baragon.models.RequestAction;
import com.hubspot.baragon.models.UpstreamInfo;

public class ServiceManager {
  private final BaragonStateDatastore stateDatastore;
  private final RequestManager requestManager;

  @Inject
  public ServiceManager(BaragonStateDatastore stateDatastore, RequestManager requestManager) {
    this.stateDatastore = stateDatastore;
    this.requestManager = requestManager;
  }

  public Collection<BaragonServiceState> getAllServices() {
    return stateDatastore.getGlobalState();
  }

  public Optional<BaragonServiceState> getService(String serviceId) {
    final Optional<BaragonService> maybeServiceInfo = stateDatastore.getService(serviceId);

    if (!maybeServiceInfo.isPresent()) {
      return Optional.absent();
    }

    try {
      return Optional.of(new BaragonServiceState(maybeServiceInfo.get(), stateDatastore.getUpstreamsMap(serviceId).values()));
    } catch (Exception e) {
      throw Throwables.propagate(e);
    }
  }

  public BaragonResponse enqueueReloadServiceConfigs(String serviceId) {
    String requestId = String.format("%s-%s-%s", serviceId, System.currentTimeMillis(), "RELOAD");
    Optional<BaragonService> maybeService = stateDatastore.getService(serviceId);
    if (maybeService.isPresent()) {
      try {
        return requestManager.enqueueRequest(buildReloadRequest(maybeService.get(), requestId));
      } catch (Exception e) {
        return BaragonResponse.failure(requestId, e.getMessage());
      }
    } else {
      return BaragonResponse.serviceNotFound(requestId, serviceId);
    }
  }

  public BaragonResponse enqueueRemoveService(String serviceId) {
    String requestId = String.format("%s-%s-%s", serviceId, System.currentTimeMillis(), "DELETE");
    Optional<BaragonService> maybeService = stateDatastore.getService(serviceId);
    if (maybeService.isPresent()) {
      try {
        return requestManager.enqueueRequest(buildRemoveRequest(maybeService.get(), requestId));
      } catch (Exception e) {
        return BaragonResponse.failure(requestId, e.getMessage());
      }
    } else {
      return BaragonResponse.serviceNotFound(requestId, serviceId);
    }
  }

  private BaragonRequest buildRemoveRequest(BaragonService service, String requestId) {
      List<UpstreamInfo> empty = Collections.emptyList();
      return new BaragonRequest(requestId, service, empty, empty, Optional.<String>absent(), Optional.of(RequestAction.DELETE));
  }

  private BaragonRequest buildReloadRequest(BaragonService service, String requestId) {
    List<UpstreamInfo> empty = Collections.emptyList();
    return new BaragonRequest(requestId, service, empty, empty, Optional.<String>absent(), Optional.of(RequestAction.RELOAD));
  }
}

@@ -32,16 +32,44 @@
 agers;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -2779,20 +2779,35 @@
 uestId) 
+throws Exception 
 %7B%0A
-  
     List
@@ -2852,24 +2852,149 @@
 tyList();%0A  
+  List%3CUpstreamInfo%3E remove;%0A    remove =  new ArrayList%3C%3E(stateDatastore.getUpstreamsMap(service.getServiceId()).values());%0A
     return n
@@ -3030,37 +3030,38 @@
 service, empty, 
+r
 em
-pty
+ove
 , Optional.%3CStri

fix service remove to have all current upstreams in remove for easier compatibility if agent doesn't support deletes