package com.rera.mss.controller

import com.rera.mss.payload.ApiResponse
import com.rera.mss.payload.InstrumentDto
import com.rera.mss.payload.InstrumentListDto
import com.rera.mss.security.CurrentUser
import com.rera.mss.security.UserPrincipal
import com.rera.mss.service.InstrumentService
import com.rera.mss.service.InstrumentServiceOperationResult
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.*
import org.springframework.web.servlet.support.ServletUriComponentsBuilder
import java.net.URI
import javax.validation.Valid

@RestController
@RequestMapping("/api/instruments")
class InstrumentController(
        private val service: InstrumentService
) {

    @PostMapping()
    @PreAuthorize("hasRole('USER')")
    fun addInstrument(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody instrument: InstrumentDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.addInstrument(currentUser, instrument)) {
            is InstrumentServiceOperationResult.Success -> buildCreatedResponseEntity("/api/instrument/{guid}", result.value)
            is InstrumentServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Sensor could not have been created"), HttpStatus.BAD_REQUEST)
        }
    }

    @GetMapping()
    @PreAuthorize("hasRole('USER')")
    fun getInstruments(
            @CurrentUser currentUser: UserPrincipal
    ): ResponseEntity<InstrumentListDto> {
        return when (val result = service.getInstruments(currentUser)) {
            is InstrumentServiceOperationResult.Success -> ResponseEntity.ok().body(result.value)
            is InstrumentServiceOperationResult.Error -> ResponseEntity.badRequest().body(InstrumentListDto(instruments = emptySet(), availableMonitoredAreas = emptySet()))
        }
    }

    @PutMapping()
    @PreAuthorize("hasRole('USER')")
    fun updateInstrument(
            @CurrentUser currentUser: UserPrincipal,
            @Valid @RequestBody instrument: InstrumentDto
    ): ResponseEntity<ApiResponse> {
        return when (val result = service.updateInstrument(currentUser, instrument)) {
            is InstrumentServiceOperationResult.Success -> ResponseEntity.ok(ApiResponse(true, "Sensor ${instrument.id} updated successfully"))
            is InstrumentServiceOperationResult.Error -> ResponseEntity(ApiResponse(false, "Sensor could not have been created"), HttpStatus.BAD_REQUEST)
        }
    }

    private fun buildCreatedResponseEntity(path: String, instrument: InstrumentDto) = ResponseEntity
            .created(createLocation(path, instrument.guid))
            .body(ApiResponse(success = true, message = "Sensor created successfully."))

    private fun createLocation(path: String, guid: String): URI = ServletUriComponentsBuilder
            .fromCurrentContextPath()
            .path(path)
            .buildAndExpand(guid)
            .toUri()
}