package ch.carve.consul;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Schedule;
import javax.ejb.Singleton;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.orbitz.consul.Consul;
import com.orbitz.consul.model.health.ServiceHealth;

@Singleton
public class ConsulServiceDiscovery {
    private static final Logger logger = LoggerFactory.getLogger(ConsulServiceDiscovery.class);

    private static Consul consul = Consul.builder().withUrl("http://192.168.99.100:8500").build();

    private Map<String, List<String>> hosts = new HashMap<>();

    @Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
    public void timer() {
        hosts.keySet().stream().forEach((k) -> hosts.put(k, getUpdatedListOfServers(k)));
    }

    public URI resolve(URI uri) {
        String service = uri.getHost();
        List<String> list = hosts.get(service);
        if (list == null || list == Collections.EMPTY_LIST) {
            list = getUpdatedListOfServers(service);
            hosts.put(service, list);
        }
        String newHost = filter(list);
        URI newUri = URI.create("http://" + newHost + uri.getPath());
        return newUri;
    }

    public void notifyError(String service) {
        logger.info("Service {} marked for reload", service);
        hosts.remove(service);
    }

    private String filter(List<String> list) {
        return list.get(0);
    }

    private List<String> getUpdatedListOfServers(String service) {
        List<String> result = new ArrayList<>();
        List<ServiceHealth> nodes = consul.healthClient().getHealthyServiceInstances(service).getResponse();
        for (ServiceHealth node : nodes) {
            result.add(node.getService().getAddress() + ":" + node.getService().getPort());
        }
        logger.info("updated server list for service {} : {}", service, result);
        return result;
    }

}

@@ -389,16 +389,72 @@
 lth;%0D%0A%0D%0A
+/**%0D%0A * Service Discovery with Consul as backend.%0D%0A */%0D%0A
 @Singlet
@@ -789,17 +789,17 @@
 nd = %22*/
-1
+3
 0%22, minu
@@ -960,32 +960,164 @@
 k)));%0D%0A    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Exchange service name with a healthy host:port in %7B@link URI%7D%0D%0A     * %0D%0A     * @param uri%0D%0A     * @return%0D%0A     */%0D%0A
     public URI r
@@ -1532,24 +1532,189 @@
 ;%0D%0A    %7D%0D%0A%0D%0A
+    /**%0D%0A     * Notify after an error occured with this service. Triggers a reload of%0D%0A     * hosts from the consul server%0D%0A     * %0D%0A     * @param service%0D%0A     */%0D%0A
     public v
@@ -1844,32 +1844,32 @@
 ice);%0D%0A    %7D%0D%0A%0D%0A
-
     private Stri
@@ -1896,24 +1896,94 @@
 g%3E list) %7B%0D%0A
+        // future: get local host first if available, or loadbalance%0D%0A
         retu

add some doc