package com.microservices.pms.productLibrary.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.PageUtils;
import com.microservices.common.core.web.page.GenericsTableDataInfo;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.productLibrary.domain.PmsProductLibraryRepositories;
import com.microservices.pms.productLibrary.domain.ProductLibraryRepositoriesFormatEnum;
import com.microservices.pms.productLibrary.domain.vo.NexusHostedRepoInputVo;
import com.microservices.pms.productLibrary.domain.vo.PmsProductLibrarySnapshotSimpleVo;
import com.microservices.pms.productLibrary.domain.vo.ProductRepositoriesSnapshotInputVo;
import com.microservices.pms.productLibrary.mapper.PmsProductLibraryRepositoriesMapper;
import com.microservices.pms.productLibrary.service.IPmsProductLibraryAsyncService;
import com.microservices.pms.productLibrary.service.IPmsProductLibraryRepositoriesService;
import com.microservices.pms.productLibrary.service.IPmsProductLibrarySnapshotRepoService;
import com.microservices.pms.utils.NexusRequestHelper;
import com.microservices.pms.utils.NexusRequestUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * @author OTTO
 */
@Service
public class PmsProductLibrarySnapshotRepoServiceImpl implements IPmsProductLibrarySnapshotRepoService {

    @Autowired
    private PmsProductLibraryRepositoriesMapper pmsProductLibraryRepositoriesMapper;

    @Autowired
    @Lazy
    private IPmsProductLibraryRepositoriesService pmsProductLibraryRepositoriesService;
    @Autowired
    private IPmsProductLibraryAsyncService pmsProductLibraryAsyncService;
    @Autowired
    private NexusRequestHelper nexusRequestHelper;


    @Override
    public GenericsTableDataInfo<PmsProductLibrarySnapshotSimpleVo> selectPmsProductLibrarySnapshotPageList(String enterpriseIdentifier, String repoName, String snapshotName) {
        return PageUtils.toPage(
                pmsProductLibraryRepositoriesMapper.selectPmsProductLibrarySnapshotPageList(enterpriseIdentifier, repoName, snapshotName),
                PmsProductLibraryRepositories::toPmsProductLibrarySnapshotSimpleVo);
    }


    @Override
    public int deletePmsProductLibrarySnapshotRepoByName(String enterpriseIdentifier, String repoName, String snapshotName) {
        PmsProductLibraryRepositories snapshotRepo = selectPmsProductLibrarySnapshotByName(enterpriseIdentifier, repoName, snapshotName);
        pmsProductLibraryRepositoriesService.checkLockRepositoryStatus(enterpriseIdentifier, snapshotRepo.getId());
        // 调用制品库删除接口删除制品库
        nexusRequestHelper.doRequest(
                NexusRequestUrl.DELETE_REPOSITORIES(snapshotRepo.getNexusRepositoriesName())
        );
        return pmsProductLibraryRepositoriesMapper.deletePmsProductLibraryRepositoriesById(snapshotRepo.getId());
    }

    @Override
    public PmsProductLibraryRepositories selectPmsProductLibrarySnapshotByName(String enterpriseIdentifier, String repoName, String snapshotName) {
        PmsProductLibraryRepositories pmsProductLibraryRepositories =
                pmsProductLibraryRepositoriesMapper.selectPmsProductLibrarySnapshotByName(enterpriseIdentifier, repoName, snapshotName);
        if (pmsProductLibraryRepositories == null) {
            throw new ServiceException("组织下不存在该快照库(组织标识[%s],制品库标识[%s],快照库标识[%s])", enterpriseIdentifier, repoName, snapshotName);
        }
        return pmsProductLibraryRepositories;
    }

    @Override
    public PmsProductLibrarySnapshotSimpleVo selectPmsProductLibrarySnapshotDataByName(String enterpriseIdentifier, String repoName, String snapshotName) {
        PmsProductLibraryRepositories pmsProductLibraryRepositories =
                selectPmsProductLibrarySnapshotByName(enterpriseIdentifier, repoName, snapshotName);
        return pmsProductLibraryRepositories.toPmsProductLibrarySnapshotSimpleVo();
    }


    @Override
    public Long insertPmsProductLibrarySnapshot(ProductRepositoriesSnapshotInputVo snapshotInputVo) {
        // 快照库标识根据时分秒生成名称
        snapshotInputVo.setName(DateUtils.dateTimeNow());
        PmsProductLibraryRepositories repo =
                pmsProductLibraryRepositoriesService.selectPmsProductLibraryRepositoriesByName(snapshotInputVo.getEnterpriseIdentifier(), snapshotInputVo.getRepoName());
        pmsProductLibraryRepositoriesService.checkLockRepositoryStatus(snapshotInputVo.getEnterpriseIdentifier(), repo.getId());
        if (ProductLibraryRepositoriesFormatEnum.DOCKER.getKey().equals(repo.getFormat())) {
            throw new ServiceException("Docker格式制品库不支持创建快照");
        }
        // 校验制品库标识
        Integer count = pmsProductLibraryRepositoriesMapper.selectRepositoriesSnapshotBySnapshotNameCount(
                snapshotInputVo.getEnterpriseIdentifier(),
                repo.getName(),
                snapshotInputVo.getName());
        if (count > 0) {
            throw new ServiceException("该制品库下已存在相同快照库标识(制品库标识[%s],快照库标识[%s])", repo.getName(), snapshotInputVo.getName());
        }
        NexusHostedRepoInputVo requestBody = snapshotInputVo.toNexusRepoDataVo(repo);

        // 调用制品库创建接口创建产品库
        nexusRequestHelper.doRequest(
                NexusRequestUrl.ADD_REPOSITORIES(
                        requestBody.getType(),
                        requestBody.getFormat()),
                JSONObject.from(requestBody)
        );
        // 调用制品库详情接口获取制品库详情
        NexusHostedRepoInputVo nexusDataVo = pmsProductLibraryRepositoriesService.getNexusRepo(
                repo.getType(),
                repo.getFormat(),
                PmsProductLibraryRepositories.getNexusSnapshotRepositoriesName(
                        repo.getPmsEnterpriseIdentifier(),
                        repo.getName(),
                        snapshotInputVo.getName()
                ));
        // 数据库添加该制品库
        PmsProductLibraryRepositories snapshotRepo = snapshotInputVo.toPmsProductLibraryRepositories(repo);
        snapshotRepo.setUrl(nexusDataVo.getUrl());
        snapshotRepo.setCreateTime(DateUtils.getNowDate());
        snapshotRepo.setCreateBy(SecurityUtils.getUsername());
        boolean success = pmsProductLibraryRepositoriesMapper.insertPmsProductLibraryRepositories(snapshotRepo) > 0;
        pmsProductLibraryAsyncService.syncRepoToSnapshotRepo(repo, snapshotRepo);
        return snapshotRepo.getId();
    }
}
