package com.arms.api.almproject.service;

import com.arms.api.almproject.model.vo.ProjectVO;
import com.arms.api.almproject.strategy.*;
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 ProjectService {

    private final ServerInfoService serverInfoService;
    private final CloudJiraProjectStrategy cloudJiraProjectStrategy;
    private final OnpremiseJiraProjectStrategy onpremiseJiraProjectStrategy;
    private final OnpremiseRedmineProjectStrategy onpremiseRedmineProjectStrategy;

    private ProjectStrategyImpl settingProjectStrategy(ServerInfoVO serverInfoVO) {

        if (serverInfoVO == null || StringUtils.isEmpty(serverInfoVO.getType())) {
            String errorMessage = "프로젝트 전략 등록 Error: serverInfo_유형 Null " + ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg();
            log.error(errorMessage);
            throw new IllegalArgumentException(errorMessage);
        }

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

        ProjectStrategy projectStrategy;
        if (serverType == ServerType.CLOUD) {
            projectStrategy = this.cloudJiraProjectStrategy;
        }
        else if (serverType == ServerType.ON_PREMISS) {
            projectStrategy = this.onpremiseJiraProjectStrategy;
        }
        else if (serverType == ServerType.REDMINE_ON_PREMISS) {
            projectStrategy = this.onpremiseRedmineProjectStrategy;
        }
        else {
            throw new IllegalArgumentException("프로젝트 전략 확인 Error: 허용하지 않는 serverInfo_유형입니다. :: "+
                                                    serverType+ " :: " + ErrorCode.SERVER_TYPE_INFO_ERROR.getErrorMsg());
        }

        ProjectStrategyImpl projectStrategyImpl = new ProjectStrategyImpl();
        projectStrategyImpl.registerProjectStrategy(projectStrategy);

        return projectStrategyImpl;
    }

    public ProjectVO getProject(String connectId, String projectKeyOrId) {

        ServerInfoVO serverInfoVO = serverInfoService.verifyServerInfo(connectId);

        ProjectStrategyImpl projectStrategy = this.settingProjectStrategy(serverInfoVO);;
        return projectStrategy.getProject(serverInfoVO, projectKeyOrId);
    }

    public List<ProjectVO> getProjectList(String connectId) {

        ServerInfoVO serverInfoVO = serverInfoService.verifyServerInfo(connectId);

        ProjectStrategyImpl projectStrategy = this.settingProjectStrategy(serverInfoVO);;
        return projectStrategy.getProjectList(serverInfoVO);
    }
}