package com.aip.gateway.api.controller;

import com.aip.gateway.api.model.request.RequestStream;
import com.aip.gateway.api.model.request.RequestStreamAllSet;
import com.aip.gateway.api.model.request.RequestStreamDel;
import com.aip.gateway.api.model.request.RequestStreamSet;
import com.aip.gateway.api.model.response.ApiResponseModel;
import com.aip.gateway.api.repository.AppRepository;
import com.aip.gateway.api.repository.GlobalConstants;
import com.aip.gateway.api.service.IApiStreamService;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Slf4j
@Tag(name = "ApiStream", description = "STREAM AIP API")
@RestController
@RequiredArgsConstructor
@CrossOrigin
@Validated
@RequestMapping("/v1/aip-api/stream")
public class ApiStreamController extends  BaseController {

    private final AppRepository appRepo;
    private final IApiStreamService service;

    @Operation(summary = "Stream Info", description = "AIP Stream Information Query.")
    @ApiResponse(responseCode = "200", description = "AIP Stream Information query Success.")
    @ApiOperation(value = "Stream Info", response = ApiResponseModel.class)
    @PostMapping(value = "info", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> getInfo(
            @Parameter(name = "req", description = "Stream 정보 요청 데이터", required = true)
            @RequestBody @Valid final RequestStream req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_INFO, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.getInfo(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/info, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Label 설정", description = "Stream AIP Label Set.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Label set success.")
    @ApiOperation(value = "Stream AIP Label 설정", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "set-label", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> setLabel(
            @Parameter(name = "req", description = "Stream AIP Label 설정 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamSet req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_SET_LABEL, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.setLabel(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/set-label, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Label Delete", description = "Stream AIP Label Delete.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Label delete success.")
    @ApiOperation(value = "Stream AIP Label 해제", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "delete-label", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> delLabel(
            @Parameter(name = "req", description = "Stream AIP Label 해제 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamDel req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_DELETE_LABEL, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.delLabel(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/delete-label, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Protection 설정", description = "Stream AIP Protection AIP.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Protection set success.")
    @ApiOperation(value = "Stream AIP Protection 설정", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "set-protection", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> setProtection(
            @Parameter(name = "req", description = "Stream AIP Protection 설정 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamSet req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_SET_PROTECTION, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.setProtection(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/set-protection, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Protection Delete", description = "Stream AIP Protection Delete.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Protection delete success.")
    @ApiOperation(value = "Stream AIP Protection 해제", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "delete-protection", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> delProtection(
            @Parameter(name = "req", description = "Stream AIP Protection 해제 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamDel req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_DELETE_PROTECTIN, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.delProtection(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/delete-protection, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Label Or Protection 설정", description = "Stream AIP Label Or Protection AIP.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Label Or Protection set success.")
    @ApiOperation(value = "Stream AIP Label Or Protection 설정", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "set-label-protection", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> setLabelProtection(
            @Parameter(name = "req", description = "Stream AIP Label Or Protection 설정 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamAllSet req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_SET_LABEL_PROTECTION, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.setLabelProtection(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/set-label-protection, {}", e.getMessage());
            return responseException(request, e);
        }
    }

    @Operation(summary = "Stream AIP Label Or Protection Delete", description = "Stream AIP Label Or Protection Delete.")
    @ApiResponse(responseCode = "200", description = "Stream AIP Label Or Protection delete success.")
    @ApiOperation(value = "Stream AIP Label Or Protection 해제", response = ApiResponseModel.class, responseContainer = "ArrayList")
    @PostMapping(value = "delete-label-protection", produces = {"application/json; charset=utf8"})
    public ResponseEntity<ApiResponseModel> delLabelProtection(
            @Parameter(name = "req", description = "Stream AIP Label Or Protection 해제 요청 데이터", required = true)
            @RequestBody @Valid final RequestStreamDel req, HttpServletRequest request)
    {
        try {
            GlobalConstants.setAuthorization(request, GlobalConstants.API_STREAM_DELETE_LABEL_PROTECTION, req.getApiKey(), req);
            int authError = this.appRepo.checkApiKeyValidation(req.getApiKey(), getRemoteIP(request));
            if (authError != 0) {
                return responseApiKeyValidationError(request, authError);
            }
            return responseSuccess(this.service.delLabelProtection(req));
        }
        catch (Exception e) {
            log.error("exception: /v1/aip-api/stream/delete-label-protection, {}", e.getMessage());
            return responseException(request, e);
        }
    }

}
