package com.css.simulation.resource.scene.service;

import api.common.pojo.constants.DictConstants;
import api.common.pojo.po.scene.SceneEvaluationRulePO;
import api.common.pojo.po.system.SceneImportPO;
import api.common.util.FileUtil;
import api.common.util.ObjectUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.css.simulation.resource.scene.mapper.SceneEvaluationRuleMapper;
import com.css.simulation.resource.scene.mapper.SceneImportMapper;
import com.css.simulation.resource.scene.common.utils.PoUtil;
import io.minio.MinioClient;
import io.minio.RemoveObjectArgs;
import io.minio.UploadObjectArgs;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.List;

@Service
public class SceneImportService {

    //场景目录中必须包含的子文件夹
    @Value("${scene.sub-directory}")
    String subDirectory = "Scenarios";

    //minio仓库名
    @Value("${minio.bucket-name}")
    String bucketName;

    @Resource
    SceneImportMapper sceneImportMapper;

    @Resource(name = "minioClientPrivate")
    MinioClient minioClient;

    @Resource
    SceneEvaluationRuleMapper sceneEvaluationRuleMapper;

    @SneakyThrows
    public Boolean startImport(SceneImportPO po) {
        //minio路径生成
        String sceneType = po.getSceneType();
        Integer nowTime = TimeUtil.getRq(new Date(), 0);
        String randomCode = StringUtil.getRandomCode();
        String sceneName;
        if (DictConstants.SCENE_NATURAL.equals(sceneType)) {
            sceneName = "自然驾驶场景";
        } else if (DictConstants.SCENE_STANDARD.equals(sceneType)) {
            sceneName = "标准法规场景";
        } else if (DictConstants.SCENE_ACCIDENT.equals(sceneType)) {
            sceneName = "交通事故场景";
        } else if (DictConstants.SCENE_REFERENCE_LIB.equals(sceneType)) {
            sceneName = "基准场景库";
        } else {
            return false;
        }
        String objectPath = sceneName + "/" + nowTime + "/" + randomCode + "/";
        //数据上传
        String dataDirectory = po.getDataDirectory();
        List<String> list = FileUtil.list(dataDirectory);
        for (String fileName : list) {
            //minio路径完善
            String objectName = fileName.replace(dataDirectory, objectPath).replaceAll("\\\\", "/");
            minioClient.uploadObject(UploadObjectArgs.builder()
                    .filename(fileName)
                    .bucket(bucketName)
                    .object(objectName)
                    .build());
        }
        po.setDataDirectory(objectPath);
        return true;
    }

    public Boolean checkDirectory(SceneImportPO po) {
        try {
            String dataDirectory = po.getDataDirectory() + File.separator + subDirectory;
            List<String> ls = FileUtil.ls(dataDirectory);
            return ObjectUtil.isNotNull(ls);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public void updateStatus(SceneImportPO po) {
        PoUtil.initUpdatePo(po);
        sceneImportMapper.updateStatus(po);
    }

    public void updateSceneEvaluationRule(SceneEvaluationRulePO sceneEvaluationRulePO) {
        sceneEvaluationRuleMapper.updateSceneEvaluationRule(sceneEvaluationRulePO);
    }

    @SneakyThrows
    public boolean startUploadEvaluationScript(String objectPath, String fileName, String localPath) {
        //minio路径完善
        String objectName = objectPath + fileName;
        minioClient.uploadObject(UploadObjectArgs.builder()
                .filename(localPath)
                .bucket(bucketName)
                .object(objectName)
                .build());
        return true;
    }

    public SceneEvaluationRulePO querySceneEvaluationRuleById(String id) {
        return sceneEvaluationRuleMapper.querySceneEvaluationRuleById(id);
    }

    @SneakyThrows
    public void deleteOldSceneEvaluationRuleFile(String path) {
        minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(path).build());
    }

}
