package de.rwth.idsg.bikeman.ixsi.service;

import de.rwth.idsg.bikeman.domain.Station;
import de.rwth.idsg.bikeman.ixsi.IXSIConstants;
import de.rwth.idsg.bikeman.ixsi.endpoint.Producer;
import de.rwth.idsg.bikeman.ixsi.repository.QueryIXSIRepository;
import de.rwth.idsg.bikeman.ixsi.store.PlaceAvailabilityStore;
import de.rwth.idsg.bikeman.repository.StationRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xjc.schema.ixsi.IxsiMessageType;
import xjc.schema.ixsi.PlaceAvailabilityPushMessageType;
import xjc.schema.ixsi.PlaceAvailabilityType;
import xjc.schema.ixsi.ProviderPlaceIDType;
import xjc.schema.ixsi.SubscriptionMessageType;

import java.util.Arrays;
import java.util.Set;

/**
 * @author Sevket Goekay <goekay@dbis.rwth-aachen.de>
 * @since 10.11.2014
 */
@Slf4j
@Service
public class PlaceAvailabilityPushService {

    @Autowired private Producer producer;
    @Autowired private PlaceAvailabilityStore placeAvailabilityStore;
    @Autowired private QueryIXSIRepository queryIXSIRepository;
    @Autowired private StationRepository stationRepository;

    public void reportChange(String placeID) {
        Set<String> systemIdSet = placeAvailabilityStore.getSubscribedSystems(placeID);
        if (systemIdSet.isEmpty()) {
            log.debug("Will not push. There is no subscribed system for placeID '{}'", placeID);
            return;
        }

        Integer freeSlots = getFreeSlots(placeID);

        ProviderPlaceIDType placeIDType = new ProviderPlaceIDType()
                .withPlaceID(placeID)
                .withProviderID(IXSIConstants.Provider.id);

        PlaceAvailabilityType avail = new PlaceAvailabilityType()
                .withAvailability(freeSlots)
                .withID(placeIDType);

        PlaceAvailabilityPushMessageType push = new PlaceAvailabilityPushMessageType().withPlaceAvailability(avail);
        SubscriptionMessageType sub = new SubscriptionMessageType().withPushMessageGroup(push);
        IxsiMessageType ixsi = new IxsiMessageType().withSubscriptionMessage(sub);

        producer.send(ixsi, systemIdSet);
    }

    /**
     * If the station is inoperative/deleted, the place availability based on slot state does not matter.
     */
    private Integer getFreeSlots(String placeID) {
        Station station = stationRepository.findByManufacturerId(placeID);
        switch (station.getState()) {
            case OPERATIVE:
                return queryIXSIRepository.placeAvailability(Arrays.asList(placeID))
                                          .get(0)
                                          .getAvailableSlots();
            case INOPERATIVE:
            case DELETED:
                return 0;
            default:
                throw new RuntimeException("Unexpected state");
        }
    }
}

@@ -41,52 +41,8 @@
 e;%0A%0A
-import de.rwth.idsg.bikeman.domain.Station;%0A
 impo
@@ -85,16 +85,16 @@
 stants;%0A
+
 import d
@@ -269,66 +269,8 @@
 re;%0A
-import de.rwth.idsg.bikeman.repository.StationRepository;%0A
 impo
@@ -1016,68 +1016,8 @@
 ory;
-%0A    @Autowired private StationRepository stationRepository;
 %0A%0A  
@@ -1346,28 +1346,191 @@
 s = 
-getFreeSlots(placeID
+queryIXSIRepository.placeAvailability(Arrays.asList(placeID))%0A                                               .get(0)%0A                                               .getAvailableSlots(
 );%0A%0A
@@ -2139,24 +2139,24 @@
 sage(sub);%0A%0A
+
         prod
@@ -2194,704 +2194,7 @@
    %7D
-%0A%0A    /**%0A     * If the station is inoperative/deleted, the place availability based on slot state does not matter.%0A     */%0A    private Integer getFreeSlots(String placeID) %7B%0A        Station station = stationRepository.findByManufacturerId(placeID);%0A        switch (station.getState()) %7B%0A            case OPERATIVE:%0A                return queryIXSIRepository.placeAvailability(Arrays.asList(placeID))%0A                                          .get(0)%0A                                          .getAvailableSlots();%0A            case INOPERATIVE:%0A            case DELETED:%0A                return 0;%0A            default:%0A                throw new RuntimeException(%22Unexpected state%22);%0A        %7D%0A    %7D
 %0A%7D%0A

delete redundant method