package org.synyx.urlaubsverwaltung.availability.api;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.synyx.urlaubsverwaltung.api.RestApiDateFormat;
import org.synyx.urlaubsverwaltung.person.Person;
import org.synyx.urlaubsverwaltung.person.PersonService;
import org.synyx.urlaubsverwaltung.security.SecurityRules;

import java.time.LocalDate;
import java.util.Optional;


@Api("Availabilities: Get all availabilities for a certain period")
@RestController("restApiAvailabilityController")
@RequestMapping("/api")
public class AvailabilityApiController {

    private final PersonService personService;
    private final AvailabilityService availabilityService;

    @Autowired
    AvailabilityApiController(AvailabilityService availabilityService, PersonService personService) {

        this.availabilityService = availabilityService;
        this.personService = personService;
    }

    @ApiOperation(
        value = "Get all availabilities for a certain period and person",
        notes =
            "Get all availabilities for a certain period and person. Maximum allowed period per request is one month."
    )
    @GetMapping("/availabilities")
    @PreAuthorize(SecurityRules.IS_OFFICE)
    public AvailabilityListDto personsAvailabilities(
        @ApiParam(value = "start of interval to get availabilities from (inclusive)", defaultValue = RestApiDateFormat.EXAMPLE_FIRST_DAY_OF_YEAR)
        @RequestParam("from")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
            LocalDate startDate,
        @ApiParam(value = "end of interval to get availabilities from (inclusive)", defaultValue = RestApiDateFormat.EXAMPLE_LAST_DAY_OF_MONTH)
        @RequestParam("to")
        @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
            LocalDate endDate,
        @ApiParam(value = "id of the person")
        @RequestParam(value = "person")
            Integer personId) {

        final Optional<Person> optionalPerson = personService.getPersonByID(personId);

        if (optionalPerson.isEmpty()) {
            throw new IllegalArgumentException("No person found for id = " + personId);
        }

        if (startDate.isAfter(endDate)) {
            throw new IllegalArgumentException("startdate " + startDate + " must not be after endDate " + endDate);
        }

        boolean requestedDateRangeIsMoreThanOneMonth = startDate.minusDays(1).isBefore(endDate.minusMonths(1));

        if (requestedDateRangeIsMoreThanOneMonth) {
            throw new IllegalArgumentException("Requested date range to large. Maximum allowed range is one month");
        }

        return availabilityService.getPersonsAvailabilities(startDate, endDate, optionalPerson.get());
    }
}

@@ -1022,16 +1022,17 @@
 ng(%22/api
+/
 %22)%0Apubli
@@ -1064,24 +1064,90 @@
 ntroller %7B%0A%0A
+    public static final String AVAILABILITIES = %22availabilities%22;%0A
     private 
@@ -1720,25 +1720,22 @@
 ing(
-%22/availabilities%22
+AVAILABILITIES
 )%0A  

extract constant