package it.bgates.remotebe.controller; import it.bgates.remotebe.controller.beans.FilterBean; import it.bgates.remotebe.entities.Phone; import it.bgates.remotebe.exception.InsufficientCreditException; import it.bgates.remotebe.exception.NotFoundException; import it.bgates.remotebe.exception.PermissionDeniedException; import it.bgates.remotebe.exception.UserNotFoundException; import it.bgates.remotebe.service.PhoneService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.security.Principal; import java.util.List; import static org.springframework.http.HttpStatus.*; import static org.springframework.http.ProblemDetail.forStatus; @RestController @RequestMapping("/phones") @RequiredArgsConstructor public class PhoneController { private final PhoneService phoneService; /** * Retrieves a list of phones associated with a specific device ID. * * @param id the unique identifier of the device whose associated phones are to be retrieved * @param principal the security principal of the currently authenticated user * @return a ResponseEntity containing a list of phones associated with the specified device ID; * returns a 412 status if the user is not found or a 404 status if the device or its phones are not found */ @GetMapping("/{id}") public ResponseEntity> getDevicePhones(@PathVariable Integer id, Principal principal) { try { List phones = phoneService.getPhonesByDeviceId(id, principal); return ResponseEntity.ok(phones); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } catch(NotFoundException e) { return ResponseEntity.status(NOT_FOUND).build(); } } /** * Adds a new phone entity associated with the authenticated user. * * @param phone the phone entity to be added * the phone entity should contain the device (at least the "id" field) to * which the phone will be associated * @param principal the security principal of the currently authenticated user * @return a ResponseEntity containing the added phone entity if successful; * returns a 500 status with error details if an InsufficientCreditException occurs, * a 412 status if the user is not found, or a 500 status for other exceptions **/ @PostMapping("") public ResponseEntity addPhone(@RequestBody Phone phone, Principal principal) { try { return ResponseEntity.ok(phoneService.addPhone(phone, principal)); } catch (InsufficientCreditException ex) { ProblemDetail pd = forStatus(500); pd.setDetail(ex.getMessage()); return ResponseEntity.of(pd).build(); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } catch (Exception e) { ProblemDetail pd = forStatus(HttpStatus.INTERNAL_SERVER_ERROR); pd.setDetail(e.getMessage()); return ResponseEntity.of(pd).build(); } } /** * Deletes the phone entities associated with a specified id. * The service checks if the current user is authorized to access the device * that has the phone. Throws exception if not, else mark the phone number * for deletion and synchronization. * On next send-configuration, the phone is removed from the device using * the SMS delete command, and the phone is remove ONLY IF it has * from and to dates set (temporary number). * * @param id the unique identifier of the phone to be deleted * @param principal the security principal of the currently authenticated user * @return a ResponseEntity containing a boolean value indicating the success of the deletion; * returns a 412 status if the user is not found, * a 404 status if the device or phones are not found, * or a 500 status with error details for a permission denial */ @DeleteMapping("/{id}") public ResponseEntity deleteDevicePhones(@PathVariable Integer id, Principal principal) { try { boolean res = phoneService.deletePhones(id, principal); return ResponseEntity.ok(res); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } catch(NotFoundException e) { return ResponseEntity.status(NOT_FOUND).build(); } catch (PermissionDeniedException e) { ProblemDetail pd = forStatus(HttpStatus.INTERNAL_SERVER_ERROR); pd.setDetail(e.getMessage()); return ResponseEntity.of(pd).build(); } } /** * Filters a list of phones based on the specified device ID and optional filter criteria. * * @param deviceId the unique identifier of the device to filter phones for * @param filterBean the filter criteria for phones; can be null if no filtering is required * @param principal the security principal of the currently authenticated user * @return a ResponseEntity containing the list of filtered phones if successful */ @PostMapping("/filter/{deviceId}") public ResponseEntity> filter( @PathVariable() Integer deviceId, @RequestBody(required = false) FilterBean filterBean, Principal principal ) { try { String filter = (filterBean != null) ? filterBean.getFilter() : null; List phones = phoneService.filter(deviceId, filter, principal); return ResponseEntity.ok(phones); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } } /** * Deactivates a phone associated with the specified ID. * The service ensures that the authenticated user has the necessary permissions * to deactivate the phone. If successful, the phone will no longer be active. * * @param id the unique identifier of the phone to be deactivated * @param principal the security principal of the currently authenticated user * @return a ResponseEntity containing a boolean value indicating whether the deactivation was successful; * returns a 412 status if the user is not found, or a 404 status if the phone is not found */ @GetMapping("/deactivate/{id}") public ResponseEntity deactivatePhone(@PathVariable Integer id, Principal principal) { try { Boolean res = phoneService.deactivatePhone(id, principal); return ResponseEntity.ok(res); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } catch (NotFoundException e) { return ResponseEntity.status(NOT_FOUND).build(); } catch (PermissionDeniedException e) { return ResponseEntity.status(UNAUTHORIZED).build(); } } /** * Activates a phone associated with the specified ID. * * @param id the unique identifier of the phone to be activated. * @param principal the authenticated user making the request. * @return a ResponseEntity containing a Boolean indicating the success of the activation, * or an appropriate HTTP status if an error occurs. */ @GetMapping("/activate/{id}") public ResponseEntity activatePhone(@PathVariable Integer id, Principal principal) { try { Boolean res = phoneService.activatePhone(id, principal); return ResponseEntity.ok(res); } catch (UserNotFoundException e) { return ResponseEntity.status(PRECONDITION_FAILED).build(); } catch (NotFoundException e) { return ResponseEntity.status(NOT_FOUND).build(); } catch (PermissionDeniedException e) { return ResponseEntity.status(UNAUTHORIZED).build(); } } }