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

import com.arms.api.issue.type.model.vo.IssueTypeVO;
import com.arms.api.serverinfo.model.vo.ServerInfoVO;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.alm.JiraUtil;
import com.arms.api.util.errors.ErrorLogUtil;
import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.domain.IssueType;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

@Component
@AllArgsConstructor
public class OnpremiseJiraIssueTypeStrategy implements IssueTypeStrategy {

    private final JiraUtil jiraUtil;

    private final ServerInfoService serverInfoService;

    @Override
    public List<IssueTypeVO> getIssueTypeList(ServerInfoVO serverInfoVO) {

        try( JiraRestClient restClient = jiraUtil.createJiraOnPremiseCommunicator(serverInfoVO.getUri(),
                serverInfoVO.getUserId(),
                serverInfoService.getDecryptPasswordOrToken(serverInfoVO.getPasswordOrToken()))) {
            Iterable<IssueType> onpremiseJiraIssueTypeList = restClient.getMetadataClient().getIssueTypes().get();

            return StreamSupport.stream(onpremiseJiraIssueTypeList.spliterator(), false)
                    .map(this::convertIssueTypeVO)
                    .collect(Collectors.toList());
        }
        catch (InterruptedException e) {
            String errorMessage =
                    ErrorLogUtil.exceptionLoggingAndReturn(e,
                            this.getClass().getName(),
                            String.format("%s[%s] :: getIssueTypeList InterruptedException Error. Thread was interrupted",
                                    serverInfoVO.getType(), serverInfoVO.getUri())
                    );
            Thread.currentThread().interrupt();
            throw new IllegalStateException(errorMessage);
        }
        catch (Exception e) {
            String errorMessage = ErrorLogUtil.exceptionLoggingAndReturn(e, this.getClass().getName(),
                    String.format("%s[%s] :: getIssueTypeList Error", serverInfoVO.getType(), serverInfoVO.getUri()));
            throw new IllegalArgumentException(errorMessage);
        }
    }

    @Override
    public List<IssueTypeVO> getIssueTypeListByProject(ServerInfoVO serverInfoVO, String projectId) { return null; }

    private IssueTypeVO convertIssueTypeVO(IssueType issueType) {
        return IssueTypeVO.builder()
                .self(issueType.getSelf().toString())
                .id(issueType.getId().toString())
                .description(issueType.getDescription())
                .name(issueType.getName())
                .subtask(issueType.isSubtask()).build();
    }
}
