package com.arms.api.issue.priority.strategy;

import com.arms.api.issue.priority.model.OnpremiseRedmineIssuePriorityDTO;
import com.arms.api.issue.priority.model.IssuePriorityDTO;
import com.arms.api.serverinfo.model.vo.ServerInfoVO;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.alm.RedmineApi;
import com.arms.api.util.alm.RedmineUtil;
import com.arms.api.util.errors.ErrorLogUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
@AllArgsConstructor
public class OnpremiseRedmineIssuePriorityStrategy implements IssuePriorityStrategy {

    private final RedmineUtil redmineUtil;

    private final RedmineApi redmineApi;

    private final ServerInfoService serverInfoService;

    @Override
    public List<IssuePriorityDTO> getIssuePriorityList(ServerInfoVO serverInfoVO) {

        WebClient webClient = redmineUtil.createRedmineWebClientCommunicator(serverInfoVO.getUri(), serverInfoService.getDecryptPasswordOrToken(serverInfoVO.getPasswordOrToken()));
        String endpoint = redmineApi.getEndpoint().getPriorityList();

        try {
            OnpremiseRedmineIssuePriorityDTO redmineIssuePriorityDTO
                    = redmineUtil.get(webClient, endpoint, OnpremiseRedmineIssuePriorityDTO.class).block();

            return Optional.ofNullable(redmineIssuePriorityDTO)
                    .map(OnpremiseRedmineIssuePriorityDTO::getIssue_priorities)
                    .orElseGet(Collections::emptyList)
                    .stream()
                    .filter(Objects::nonNull)
                    .filter(OnpremiseRedmineIssuePriorityDTO.IssuePriority::isActive)
                    .map(issuePriority -> convertIssuePriorityDTO(issuePriority, serverInfoVO.getUri()))
                    .collect(Collectors.toList());
        }
        catch (Exception e) {
            String errorMessage = ErrorLogUtil.exceptionLoggingAndReturn(e, this.getClass().getName(),
                    String.format("%s[%s] :: getIssuePriorityList Error",
                            serverInfoVO.getType(), serverInfoVO.getUri()));
            throw new IllegalArgumentException(errorMessage);
        }
    }

    private IssuePriorityDTO convertIssuePriorityDTO(OnpremiseRedmineIssuePriorityDTO.IssuePriority issuePriority, String serverInfoPath) {
        IssuePriorityDTO IssuePriorityDTO = new IssuePriorityDTO();

        IssuePriorityDTO.setId(String.valueOf(issuePriority.getId()));
        IssuePriorityDTO.setName(issuePriority.getName());
        IssuePriorityDTO.setDefault(issuePriority.is_default());
        IssuePriorityDTO.setSelf(redmineUtil.checkServerInfoPath(serverInfoPath) + redmineApi.replaceID(redmineApi.getEndpoint().getPriority(), String.valueOf(issuePriority.getId())));

        return IssuePriorityDTO;
    }
}
