package com.arms.api.project.strategy;

import com.arms.api.project.vo.ProjectVO;
import com.arms.api.serverinfo.model.ServerInfo;
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.BasicProject;
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 OnpremiseJiraProjectStrategy implements ProjectStrategy {

    private final JiraUtil jiraUtil;

    private final ServerInfoService serverInfoService;

    @Override
    public ProjectVO getProject(ServerInfo serverInfo, String projectKeyOrId) {

        JiraRestClient restClient = jiraUtil.createJiraOnPremiseCommunicator(serverInfo.getUri(),
                serverInfo.getUserId(),
                serverInfoService.getDecryptPasswordOrToken(serverInfo));

        try {
            BasicProject basicProject = restClient.getProjectClient()
                    .getProject(projectKeyOrId)
                    .claim();

            return this.convertProjectVO(basicProject);
        }
        catch (Exception e) {
            String errorMessage = ErrorLogUtil.exceptionLoggingAndReturn(e, this.getClass().getName(),
                    String.format("%s[%s] :: getProject Error 프로젝트[%s] ",
                            serverInfo.getType(), serverInfo.getUri(), projectKeyOrId));
            throw new IllegalArgumentException(errorMessage);
        }
    }

    @Override
    public List<ProjectVO> getProjectList(ServerInfo serverInfo) {

        JiraRestClient restClient = jiraUtil.createJiraOnPremiseCommunicator(serverInfo.getUri(),
                serverInfo.getUserId(),
                serverInfoService.getDecryptPasswordOrToken(serverInfo));

        try {
            Iterable<BasicProject> basicProjectList = restClient.getProjectClient()
                    .getAllProjects()
                    .claim();

            return StreamSupport.stream(basicProjectList.spliterator(), false)
                    .map(this::convertProjectVO)
                    .collect(Collectors.toList());
        }
        catch (Exception e) {
            String errorMessage = ErrorLogUtil.exceptionLoggingAndReturn(e, this.getClass().getName(),
                    String.format("%s[%s] :: getProjectList Error", serverInfo.getType(), serverInfo.getUri()));
            throw new IllegalArgumentException(errorMessage);
        }
    }

    private ProjectVO convertProjectVO(BasicProject project) {
        return ProjectVO.builder()
                .id(project.getId().toString())
                .key(project.getKey())
                .name(project.getName())
                .self(project.getSelf().toString()).build();
    }
}