package com.iqser.red.service.persistence.service.v1.api.external.resource;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;

import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.Rules;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;

public interface RulesResource {

    String RULES_PATH = ExternalApi.BASE_PATH + "/rules";
    String UPLOAD_PATH = "/upload";
    String DOWNLOAD_PATH = "/download";

    String DOSSIER_TEMPLATE_PARAMETER_NAME = "dossierTemplateId";
    String DOSSIER_TEMPLATE_PATH_VARIABLE = "/{dossierTemplateId}";

    String RULE_FILE_TYPE_PARAMETER_NAME = "ruleFileType";
    String RULE_FILE_TYPE_PATH_VARIABLE = "/{ruleFileType}";


    /**
     * Upload rules to be used by redaction service.
     *
     * @param rules object containing string of rules.
     */
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = RULES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
    ResponseEntity<?> upload(@RequestBody RulesUploadRequestModel rules);


    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    @Operation(summary = "Returns object containing the currently used Drools rules.")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    Rules download(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId);


    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    @Operation(summary = "Returns object containing the currently used Drools rules.")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    Rules download(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType);


    /**
     * Upload rules as file to be used by redaction service.
     *
     * @param file Drools file containing rules as plain text.
     */
    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
    ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
    ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
                                 @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType,
                                 @RequestPart(name = "file") MultipartFile file);


    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    @Operation(summary = "Returns file containing the currently used Drools rules.")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + DOWNLOAD_PATH)
    ResponseEntity<?> downloadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId);


    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    @Operation(summary = "Returns file containing the currently used Drools rules.")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    @GetMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + DOWNLOAD_PATH)
    ResponseEntity<?> downloadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType);

}
