package enmasse.storage.controller.restapi;

import enmasse.storage.controller.admin.AddressManager;
import enmasse.storage.controller.model.Destination;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
import java.util.stream.Collectors;

@Path("/v1/enmasse/addresses")
public class RestService {

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public Response getAddresses(@Context AddressManager addressManager) {
        try {
            return Response.ok(destinationsToMap(addressManager.listDestinations()), MediaType.APPLICATION_JSON_TYPE).build();
        } catch (Exception e) {
            return Response.serverError().build();
        }
    }

    @PUT
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response putAddresses(@Context AddressManager addressManager, Map<String, AddressProperties> addressMap) {
        try {
            addressManager.destinationsUpdated(mapToDestinations(addressMap));
            return Response.ok(addressMap).build();
        } catch (Exception e) {
            return Response.serverError().build();
        }
    }

    @DELETE
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response deleteAddresses(@Context AddressManager addressManager, List<String> data) {
        try {
            Set<Destination> destinations = addressManager.listDestinations();
            for (String address : data) {
                destinations.removeIf(dest -> dest.address().equals(address));
            }
            addressManager.destinationsUpdated(destinations);
            return Response.ok(destinationsToMap(destinations)).build();
        } catch (Exception e) {
            return Response.serverError().build();
        }
    }

    @POST
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_JSON})
    public Response appendAddresses(@Context AddressManager addressManager, Map<String, AddressProperties> addressMap) {
        try {
            Set<Destination> destinations = new HashSet<>(addressManager.listDestinations());
            destinations.addAll(mapToDestinations(addressMap));
            addressManager.destinationsUpdated(destinations);

            return Response.ok(destinationsToMap(destinations)).build();
        } catch (Exception e) {
            return Response.serverError().build();
        }
    }

    private static Set<Destination> mapToDestinations(Map<String, AddressProperties> addressMap) {
        return addressMap.entrySet().stream()
                .map(e -> new Destination(e.getKey(), e.getValue().store_and_forward, e.getValue().multicast, e.getValue().flavor))
                .collect(Collectors.toSet());
    }

    private static Map<String, AddressProperties> destinationsToMap(Collection<Destination> destinations) {
        Map<String, AddressProperties> map = new LinkedHashMap<>();
        for (Destination destination : destinations) {
            map.put(destination.address(), new AddressProperties(destination.storeAndForward(), destination.multicast(), destination.flavor()));
        }
        return map;
    }
}

@@ -146,16 +146,73 @@
 ination;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -398,28 +398,8 @@
 h(%22/
-v1/enmasse/addresses
 %22)%0Ap
@@ -423,16 +423,108 @@
 ervice %7B
+%0A    private static final Logger log = LoggerFactory.getLogger(RestService.class.getName());
 %0A%0A    @G
@@ -562,32 +562,67 @@
 LICATION_JSON%7D)%0A
+    @Path(%22/v1/enmasse/addresses%22)%0A
     public Respo
@@ -686,32 +686,78 @@
 %7B%0A        try %7B%0A
+            log.info(%22Retrieving addresses%22);%0A
             retu
@@ -891,32 +891,88 @@
 (Exception e) %7B%0A
+            log.error(%22Error retrieving addresses%22, e);%0A
             retu
@@ -1112,32 +1112,67 @@
 LICATION_JSON%7D)%0A
+    @Path(%22/v1/enmasse/addresses%22)%0A
     public Respo
@@ -1279,32 +1279,77 @@
 %7B%0A        try %7B%0A
+            log.info(%22Replacing addresses%22);%0A
             addr
@@ -1487,32 +1487,87 @@
 (Exception e) %7B%0A
+            log.error(%22Error replacing addresses%22, e);%0A
             retu
@@ -1710,32 +1710,67 @@
 LICATION_JSON%7D)%0A
+    @Path(%22/v1/enmasse/addresses%22)%0A
     public Respo
@@ -1856,32 +1856,76 @@
 %7B%0A        try %7B%0A
+            log.info(%22Deleting addresses%22);%0A
             Set%3C
@@ -2281,32 +2281,83 @@
 (Exception e) %7B%0A
+            log.error(%22Error deleting addresses%22);%0A
             retu
@@ -2502,24 +2502,59 @@
 TION_JSON%7D)%0A
+    @Path(%22/v1/enmasse/addresses%22)%0A
     public R
@@ -2668,32 +2668,77 @@
 %7B%0A        try %7B%0A
+            log.info(%22Appending addresses%22);%0A
             Set%3C
@@ -3039,32 +3039,84 @@
 (Exception e) %7B%0A
+            log.error(%22Error appending addresses%22);%0A
             retu

Add some debug info