# ApiController.java

    package io.github.js0ny.ilp_coursework.controller;

    import io.github.js0ny.ilp_coursework.data.common.Angle;
    import io.github.js0ny.ilp_coursework.data.common.LngLat;
    import io.github.js0ny.ilp_coursework.data.common.Region;
    import io.github.js0ny.ilp_coursework.data.request.DistanceRequest;
    import io.github.js0ny.ilp_coursework.data.request.MovementRequest;
    import io.github.js0ny.ilp_coursework.data.request.RegionCheckRequest;
    import io.github.js0ny.ilp_coursework.service.GpsCalculationService;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    /**
     * Main REST Controller for the ILP Coursework 1 application.
     *
     * <p>This class handles incoming HTTP requests for the API under {@code /api/v1} path (defined in
     * CW1) This is responsible for mapping requests to the appropriate service method and returning the
     * results as responses. The business logic is delegated to {@link GpsCalculationService}
     */
    @RestController
    @RequestMapping("/api/v1")
    public class ApiController {

        private static final Logger log = LoggerFactory.getLogger(ApiController.class);

        private final GpsCalculationService gpsService;

        /**
         * Constructor of the {@code ApiController} with the business logic dependency {@code
         * GpsCalculationService}
         *
         * @param gpsService The service component that contains all business logic, injected by
         *     Spring's DI.
         */
        public ApiController(GpsCalculationService gpsService) {
            this.gpsService = gpsService;
        }

        /**
         * Handles GET requests to retrieve the student's Unique ID
         *
         * @return A string representing the student ID starting with s
         */
        @GetMapping("/uid")
        public String getUid() {
            log.info("GET /api/v1/uid");
            return "s2522255";
        }

        /**
         * Handles POST requests to get the distance between two positions
         *
         * @param request A {@link DistanceRequest} containing the two coordinates
         * @return A {@code double} representing the calculated distance
         */
        @PostMapping("/distanceTo")
        public double getDistance(@RequestBody DistanceRequest request) {
            LngLat position1 = request.position1();
            LngLat position2 = request.position2();
            log.info("POST /api/v1/distanceTo position1={} position2={}", position1, position2);
            return gpsService.calculateDistance(position1, position2);
        }

        /**
         * Handles POST requests to check if the two coordinates are close to each other
         *
         * @param request A {@link DistanceRequest} containing the two coordinates
         * @return {@code true} if the distance is less than the predefined threshold, {@code false}
         *     otherwise
         */
        @PostMapping("/isCloseTo")
        public boolean getIsCloseTo(@RequestBody DistanceRequest request) {
            LngLat position1 = request.position1();
            LngLat position2 = request.position2();
            log.info("POST /api/v1/isCloseTo position1={} position2={}", position1, position2);
            return gpsService.isCloseTo(position1, position2);
        }

        /**
         * Handles POST requests to get the next position after an angle of movement
         *
         * @param request A {@link MovementRequest} containing the start coordinate and angle of the
         *     movement.
         * @return A {@link LngLat} representing the destination
         */
        @PostMapping("/nextPosition")
        public LngLat getNextPosition(@RequestBody MovementRequest request) {
            LngLat start = request.start();
            Angle angle = new Angle(request.angle());
            log.info("POST /api/v1/nextPosition start={} angle={}", start, angle);
            return gpsService.nextPosition(start, angle);
        }

        /**
         * Handles POST requests to check if a point is inside a given region
         *
         * @param request A {@link RegionCheckRequest} containing the coordinate and the region
         * @return {@code true} if the coordinate is inside the region, {@code false} otherwise
         */
        @PostMapping("/isInRegion")
        public boolean getIsInRegion(@RequestBody RegionCheckRequest request) {
            LngLat position = request.position();
            Region region = request.region();
            log.info("POST /api/v1/isInRegion position={} region={}", position, region);
            return gpsService.checkIsInRegion(position, region);
        }
    }