package com.iqser.red.persistence.service.v1.external.api.impl.controller;

import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_REDACTION_LOG;

import java.util.ArrayList;
import java.util.List;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.iqser.red.service.persistence.management.v1.processor.mapper.EntityLogResponseMapper;
import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
import com.iqser.red.service.persistence.service.v1.api.external.resource.EntityLogResource;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.FilteredEntityLogRequest;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class EntityLogController implements EntityLogResource {

    private final EntityLogService entityLogService;
    private final AccessControlService accessControlService;
    private final EntityLogResponseMapper entityLogResponseMapper = EntityLogResponseMapper.INSTANCE;


    @PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
    public EntityLogResponse getEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
                                          @PathVariable(FILE_ID) String fileId,
                                          @RequestParam(value = "excludedTypes", required = false, defaultValue = "") List<String> excludedTypes,
                                          @RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed) {

        accessControlService.checkViewPermissionsToDossier(dossierId);
        accessControlService.validateFileResourceExistence(fileId);
        return entityLogResponseMapper.toLogResponse(entityLogService.getEntityLog(dossierId,
                                                                                   fileId,
                                                                                   excludedTypes == null ? new ArrayList<>() : excludedTypes,
                                                                                   includeUnprocessed));
    }


    @PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
    public EntityLogResponse getFilteredEntityLog(@PathVariable(DOSSIER_ID) String dossierId,
                                                  @PathVariable(FILE_ID) String fileId,
                                                  @RequestBody FilteredEntityLogRequest filteredEntityLogRequest) {

        accessControlService.checkViewPermissionsToDossier(dossierId);
        accessControlService.validateFileResourceExistence(fileId);
        return entityLogResponseMapper.toLogResponse(entityLogService.getFilteredEntityLog(dossierId, fileId, filteredEntityLogRequest));
    }


    @PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
    public EntityLogResponse getEntityLogWithEntriesOnPages(@PathVariable(DOSSIER_ID) String dossierId,
                                                            @PathVariable(FILE_ID) String fileId,
                                                            @RequestParam(value = "pageNumbers", defaultValue = "") List<Integer> pageNumbers) {

        accessControlService.checkViewPermissionsToDossier(dossierId);
        accessControlService.validateFileResourceExistence(fileId);
        return entityLogResponseMapper.toLogResponse(entityLogService.getEntityLogWithEntriesOnPages(dossierId, fileId, pageNumbers));
    }


    @PreAuthorize("hasAuthority('" + READ_REDACTION_LOG + "')")
    public EntityLogResponse getEntityLogDeltaUpdate(@PathVariable(DOSSIER_ID) String dossierId,
                                                     @PathVariable(FILE_ID) String fileId,
                                                     @PathVariable(ANALYSIS_NUMBER) Integer analysisNumber,
                                                     @RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed) {

        accessControlService.checkViewPermissionsToDossier(dossierId);
        accessControlService.validateFileResourceExistence(fileId);
        return entityLogResponseMapper.toLogResponse(entityLogService.getEntityLogWithEntriesWithEntriesSinceAnalysisNumber(dossierId, fileId, analysisNumber, includeUnprocessed));
    }

}
