package cn.reghao.autodop.dmaster.app.service.config.impl;

import cn.reghao.autodop.dmaster.app.db.crud.config.RepoAuthConfigCrud;
import cn.reghao.autodop.dmaster.app.db.query.config.AppConfigQuery;
import cn.reghao.autodop.dmaster.app.db.query.config.RepoAuthConfigQuery;
import cn.reghao.autodop.dmaster.app.model.constant.build.RepoAuthType;
import cn.reghao.autodop.dmaster.app.model.constant.build.RepoType;
import cn.reghao.autodop.dmaster.app.model.po.config.AppConfig;
import cn.reghao.autodop.dmaster.app.model.po.config.build.RepoAuthConfig;
import cn.reghao.autodop.dmaster.app.service.config.RepoAuthConfigService;
import cn.reghao.jdkutil.result.Result;
import cn.reghao.jdkutil.result.ResultStatus;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2021-09-17 10:16:07
 */
@Service
public class RepoAuthConfigServiceImpl implements RepoAuthConfigService {
    private final RepoAuthConfigQuery repoAuthConfigQuery;
    private final RepoAuthConfigCrud repoAuthConfigCrud;
    private final AppConfigQuery appConfigQuery;

    public RepoAuthConfigServiceImpl(RepoAuthConfigQuery repoAuthConfigQuery, RepoAuthConfigCrud repoAuthConfigCrud,
                                     AppConfigQuery appConfigQuery) {
        this.repoAuthConfigQuery = repoAuthConfigQuery;
        this.repoAuthConfigCrud = repoAuthConfigCrud;
        this.appConfigQuery = appConfigQuery;
    }

    @Override
    public Result add(RepoAuthConfig repoAuthConfig) {
        Result result = valid(repoAuthConfig);
        if (result.getCode() != ResultStatus.SUCCESS.getCode()) {
            return result;
        }
        repoAuthConfigCrud.save(repoAuthConfig);
        return result;
    }

    @Override
    public Result modify(RepoAuthConfig repoAuthConfig) {
        Result result = valid(repoAuthConfig);
        if (result.getCode() != ResultStatus.SUCCESS.getCode()) {
            return result;
        }
        repoAuthConfigCrud.save(repoAuthConfig);
        return result;
    }

    private Result valid(RepoAuthConfig repoAuthConfig) {
        switch (RepoType.valueOf(repoAuthConfig.getType())) {
            case git:
                switch (RepoAuthType.valueOf(repoAuthConfig.getAuthType())) {
                    case ssh:
                        String rsaPriKey = repoAuthConfig.getRsaPrikey();
                        if (rsaPriKey.isEmpty() || rsaPriKey.isBlank()) {
                            return Result.result(ResultStatus.FAIL, "RSA 私钥不能为空");
                        }
                        break;
                    case http:
                        String username = repoAuthConfig.getUsername();
                        String password = repoAuthConfig.getPassword();
                        if (username.isEmpty() || username.isBlank() || password.isEmpty() || password.isBlank()) {
                            return Result.result(ResultStatus.FAIL, "用户名/密码不能为空");
                        }
                        break;
                    default:
                        return Result.result(ResultStatus.FAIL, "必须选择 git 的认证类型");
                }
                break;
            case svn:
                // TODO 暂未实现对 SVN 的验证
                break;
            default:
                return Result.result(ResultStatus.FAIL, "暂不支持除 GIT/SVN 之外的版本管理工具");
        }
        return Result.result(ResultStatus.SUCCESS);
    }

    @Override
    public Result delete(RepoAuthConfig repoAuthConfig) {
        List<AppConfig> apps = appConfigQuery.findAllByRepoAuthConfig(repoAuthConfig);
        if (apps.isEmpty()) {
            repoAuthConfigCrud.delete(repoAuthConfig);
            return Result.result(ResultStatus.SUCCESS);
        } else {
            List<String> ids = apps.stream().map(AppConfig::getAppId).collect(Collectors.toList());
            String msg = repoAuthConfig.getName() + " 删除失败, " + ids + " 等应用正在使用";
            return Result.result(ResultStatus.FAIL, msg);
        }
    }

    @Override
    public RepoAuthConfig get(String name) {
        return repoAuthConfigQuery.findByName(name);
    }
}
