package com.dteknoloji.controller.beaconGroup;

/*
 * This code belongs to:
 * Ahmet Emre Unal
 * S001974
 * emre.unal@ozu.edu.tr
 */

import java.util.List;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import com.dteknoloji.config.GlobalSettings;
import com.dteknoloji.domain.beacon.Beacon;
import com.dteknoloji.domain.beaconGroup.BeaconGroup;
import com.dteknoloji.service.beacon.BeaconService;
import com.dteknoloji.service.beaconGroup.BeaconGroupService;

@Controller
@RequestMapping("/BeaconGroup")
public class BeaconGroupController {
    @Autowired
    private BeaconGroupService beaconGroupService;

    @Autowired
    private BeaconService beaconService;

    /**
     * Get all beacon groups
     *
     * @return All existing beacon groups
     */
    @RequestMapping(method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<List<BeaconGroup>> getAllBeaconGroups() {
        return new ResponseEntity<List<BeaconGroup>>(beaconGroupService.findAll(), HttpStatus.OK);
    }

    /**
     * Get the beacon group with specified ID
     *
     * @param id The ID of the group
     * @return The beacon group
     */
    @RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = "application/json")
    public ResponseEntity<BeaconGroup> viewBeaconGroup(@PathVariable String id) {
        BeaconGroup beaconGroup = beaconGroupService.findById(Long.valueOf(id));
        if (beaconGroup == null) {
            return new ResponseEntity<BeaconGroup>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<BeaconGroup>(beaconGroup, HttpStatus.OK);
    }

    /**
     * Get beacon objects that belong to a group.
     *
     * @param id The ID of the group
     * @return The list of beacons that belong to the group with the specified ID
     */
    @RequestMapping(method = RequestMethod.GET, value = "/{id}/beacons", produces = "application/json")
    public ResponseEntity<List<Beacon>> viewBeaconGroupMembers(@PathVariable String id) {
        BeaconGroup beaconGroup = beaconGroupService.findById(Long.valueOf(id));
        if (beaconGroup == null) {
            return new ResponseEntity<List<Beacon>>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<List<Beacon>>(beaconGroup.getBeacons(), HttpStatus.OK);
    }

    /**
     * Create a new beacon group
     *
     * @param restBeaconGroup The beacon group as JSON object
     * @param builder
     * @return The created beacon group
     */
    @RequestMapping(method = RequestMethod.POST)
    public ResponseEntity<BeaconGroup> createBeaconGroup(@RequestBody BeaconGroup restBeaconGroup, UriComponentsBuilder builder) {
        try {
            BeaconGroup newBeaconGroup = beaconGroupService.save(restBeaconGroup);
            if (GlobalSettings.DEBUGGING) {
                System.out.println("Saved beacon group with ID = \'" + newBeaconGroup.getBeaconGroupId() + "\' name = \'" + newBeaconGroup.getName() + "\'");
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setLocation(builder.path("/BeaconGroup/{id}").buildAndExpand(newBeaconGroup.getBeaconGroupId().toString()).toUri());
            return new ResponseEntity<BeaconGroup>(newBeaconGroup, headers, HttpStatus.CREATED);
        } catch (ConstraintViolationException | TransactionSystemException e) {
            if (GlobalSettings.DEBUGGING) {
                System.err.println("Unable to save beacon group! Constraint violation detected!");
            }
            return new ResponseEntity<BeaconGroup>(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     * Add beacon to the specified beacon group
     *
     * @param beaconGroupId The ID of the beacon group to add the beacon to
     * @param beaconId      The ID of the beacon to add
     * @return The added beacon group
     */
    @RequestMapping(method = RequestMethod.POST, value = "/{beaconGroupId}/add")
    public ResponseEntity<BeaconGroup> addBeaconToGroup(@PathVariable String beaconGroupId, @RequestParam(value = "beaconId", required = true) String beaconId) {
        BeaconGroup beaconGroup = beaconGroupService.findById(Long.valueOf(beaconGroupId));
        if (beaconGroup == null) {
            return new ResponseEntity<BeaconGroup>(HttpStatus.NOT_FOUND);
        } else {
            Beacon beacon = beaconService.findById(Long.valueOf(beaconId));
            if (beacon == null) {
                return new ResponseEntity<BeaconGroup>(HttpStatus.NOT_FOUND);
            } else {
                // TODO return error if beacon is already in a group
                beacon.setGroup(beaconGroup);
                beaconGroup.getBeacons().add(beacon);
                beaconService.save(beacon);
                beaconGroupService.save(beaconGroup);
                return new ResponseEntity<BeaconGroup>(beaconGroup, HttpStatus.OK);
            }
        }
    }

    /**
     * Delete the specified beacon group
     *
     * @param id The ID of the beacon group to delete
     * @return The deleted beacon group
     */
    @RequestMapping(method = RequestMethod.DELETE, value = "/{id}", produces = "application/json")
    public ResponseEntity<BeaconGroup> deleteBeaconGroup(@PathVariable String id) {

        BeaconGroup beaconGroup = beaconGroupService.findById(Long.valueOf(id));
        if (beaconGroup == null) {
            return new ResponseEntity<BeaconGroup>(HttpStatus.NOT_FOUND);
        }

        boolean deleted = beaconGroupService.delete(Long.valueOf(id));
        if (deleted) {
            return new ResponseEntity<BeaconGroup>(beaconGroup, HttpStatus.OK);
        }

        return new ResponseEntity<BeaconGroup>(beaconGroup, HttpStatus.FORBIDDEN);
    }
}

@@ -4068,32 +4068,92 @@
 on group%0A     *%0A
+     * Can return 409 if beacon already has a group.%0A     *%0A
      * @param be
@@ -5004,61 +5004,151 @@
     
-// TODO return error if beacon is already in a group%0A
+if (beacon.getGroup() != null) %7B%0A                    return new ResponseEntity%3CBeaconGroup%3E(HttpStatus.CONFLICT);%0A                %7D else %7B%0A    
     
@@ -5197,32 +5197,36 @@
                 
+ 
+   
 beaconGroup.getB
@@ -5259,24 +5259,28 @@
             
+    
 beaconServic
@@ -5287,32 +5287,36 @@
 e.save(beacon);%0A
+    
                 
@@ -5361,32 +5361,36 @@
                 
+    
 return new Respo
@@ -5433,32 +5433,50 @@
 HttpStatus.OK);%0A
+                %7D%0A
             %7D%0A  

Add beacon group adding check