package com.arms.api.issue.status.service;

import com.arms.api.issue.status.strategy.*;
import com.arms.api.issue.status.model.vo.CloudJiraByIssueTypeIssueStatusVO;
import com.arms.api.issue.status.model.vo.IssueStatusVO;
import com.arms.api.serverinfo.model.enums.ServerType;
import com.arms.api.serverinfo.model.vo.ServerInfoVO;
import com.arms.api.serverinfo.service.ServerInfoService;
import com.arms.api.util.errors.ErrorCode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
@AllArgsConstructor
public class IssueStatusService {

    private final ServerInfoService ServerInfoService;
    private final CloudJiraIssueStatusStrategy cloudJiraIssueStatusStrategy;
    private final OnPremiseJiraIssueStatusStrategy onPremiseJiraIssueStatusStrategy;
    private final OnPremiseRedmineIssueStatusStrategy onPremiseRedmineIssueStatusStrategy;

    private IssueStatusStrategyFactory settingIssueStatusStrategy(ServerInfoVO serverInfoVO) {

        if (serverInfoVO == null || StringUtils.isEmpty(serverInfoVO.getType())) {
            log.error("지라이슈 상태 전략 등록 Error: serverInfo_유형 {}", ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
            throw new IllegalArgumentException("지라이슈 상태 전략 등록 Error: serverInfo_유형 " + ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
        }

        ServerType serverType = ServerType.typeValueOf(serverInfoVO.getType());

        IssueStatusStrategy issueStatusStrategy;
        if (serverType == ServerType.CLOUD) {
            issueStatusStrategy = this.cloudJiraIssueStatusStrategy;
        }
        else if (serverType == ServerType.ON_PREMISS) {
            issueStatusStrategy = this.onPremiseJiraIssueStatusStrategy;
        }
        else if (serverType == ServerType.REDMINE_ON_PREMISS) {
            issueStatusStrategy = this.onPremiseRedmineIssueStatusStrategy;
        }
        else {
            throw new IllegalArgumentException("이슈상태 전략 확인 Error: 허용하지 않는 serverInfo_유형입니다. :: "+ serverType+ " :: " + ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
        }

        IssueStatusStrategyFactory issueStatusStrategyFactory = new IssueStatusStrategyFactory();
        issueStatusStrategyFactory.registerIssueStatusStrategy(issueStatusStrategy);

        return issueStatusStrategyFactory;
    }

    public List<IssueStatusVO> getIssueStatusList(String connectId) {

        ServerInfoVO serverInfoVO = ServerInfoService.verifyServerInfo(connectId);

        ServerType serverType = ServerType.typeValueOf(serverInfoVO.getType());

        if (serverType == ServerType.CLOUD) {
            log.error("지라 클라우드 타입[{}] 이슈상태_목록_가져오기를 사용할 수 없습니다.",connectId);
            throw new IllegalArgumentException("클라우드 타입은 이슈 상태 목록 가져오기를 사용할 수 없습니다.");
        }

        IssueStatusStrategyFactory issueStatusStrategy = settingIssueStatusStrategy(serverInfoVO);

        List<IssueStatusVO> issueStatusList = issueStatusStrategy.getIssueStatusList(serverInfoVO);

        return issueStatusList;

    }

    public List<CloudJiraByIssueTypeIssueStatusVO> getIssueStatusListByProject(String connectId, String projectId) {

        ServerInfoVO serverInfoVO = ServerInfoService.verifyServerInfo(connectId);

        ServerType serverType = ServerType.typeValueOf(serverInfoVO.getType());

        if (serverType == ServerType.ON_PREMISS) {
            log.error("지라 온프레미스 타입[{}] getIssueStatusListByProject 사용할 수 없습니다.",connectId);
            throw new IllegalArgumentException("온프레미스 타입은 getIssueStatusListByProject 사용할 수 없습니다.");
        }
        else if (serverType == ServerType.REDMINE_ON_PREMISS) {
            log.error("레드마인_온프레미스_이슈상태_전략 {} getIssueStatusListByProject 사용하지 않습니다.",connectId);
            throw new IllegalArgumentException("레드마인 온프레미스 타입은 getIssueStatusListByProject 사용할 수 없습니다.");
        }

        IssueStatusStrategyFactory issueStatusStrategy = settingIssueStatusStrategy(serverInfoVO);

        List<CloudJiraByIssueTypeIssueStatusVO> issueStatusList
                = issueStatusStrategy.getIssueStatusListByProject(serverInfoVO, projectId);

        return issueStatusList;
    }
}
