package com.philisense.www.cloud;

import cn.hutool.core.io.resource.InputStreamResource;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.philisense.www.config.OssStorageProperties;
import com.philisense.www.exception.StorageException;
import com.philisense.www.rule.OssRule;
import com.philisense.www.utils.FileUtils;
import com.philisense.www.utils.SpringContextUtils;
import com.philisense.www.utils.StorageUtils;
import com.philisense.www.utils.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * @description : FastDF存储
 **/
public class GoFastDFSStorageService extends OssStorageService {

    private static Logger log = LogManager.getLogger(GoFastDFSStorageService.class);

    private OssStorageProperties.GoFastDFSConfig goFastDFSConfig;
    private String diskName;

    private String uploadPath;

    private OssRule ossRule;

    public GoFastDFSStorageService(OssStorageProperties.GoFastDFSConfig goFastDFSConfig, String diskName) {
        this.goFastDFSConfig = goFastDFSConfig;
        this.diskName = diskName;
        ossRule = SpringContextUtils.getBean(OssRule.class);
        this.uploadPath = StringUtils.format("{}/{}", goFastDFSConfig.getEndpoint(), goFastDFSConfig.getBucketName());
    }

    @Override
    public Map<String, Object> upload(MultipartFile file, String path) {
        try {
            path = ossRule.filePath(diskName + FileUtils.SLASH + path);
            InputStreamResource isr = new InputStreamResource(file.getInputStream(),
                    file.getOriginalFilename());

            //声明参数集合
            HashMap<String, Object> paramMap = new HashMap<>();
            //文件
            paramMap.put("file", isr);
            paramMap.put("path", StorageUtils.getFilePath(path));
            paramMap.put("output", "json");
            //上传
            String res = HttpUtil.post(uploadPath + "/upload", paramMap);
            JSONObject jsonObject = JSON.parseObject(res);
            if(!"0".equals(jsonObject.getString("retcode"))) {
                throw new StorageException("上传文件失败：" + jsonObject.toString());
            }

            Map<String, Object> fileMap = new HashMap<>();
            fileMap.put("path", path);
            fileMap.put("url", getUrl(path));
            return fileMap;
        } catch (Exception e) {
            log.error("上传文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("上传文件失败", e);
        }
    }

    @Override
    public Map<String, Object> upload(byte[] data, String path) {
        throw new StorageException("暂未实现该功能");
    }

    @Override
    public InputStream download(String path) {
        try {
            final ByteArrayOutputStream output = new ByteArrayOutputStream();
            HttpUtil.download(getUrl(path), output, false);
            return new ByteArrayInputStream(output.toByteArray());
        } catch (Exception e) {
            log.error("下载文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("下载文件失败", e);
        }
    }

    @Override
    public void delete(String path) {
        try {
            String res = HttpUtil.post(uploadPath + "/delete?path=/" + goFastDFSConfig.getBucketName() + FileUtils.SLASH + path, new HashMap<>());
            JSONObject jsonObject = JSON.parseObject(res);
            if(!"ok".equals(jsonObject.getString("status"))) {
                throw new StorageException("删除文件失败：" + jsonObject.toString());
            }
        } catch (Exception e) {
            log.error("删除文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("删除文件失败", e);
        }
    }

    @Override
    public String getUrl(String path) {
        return StringUtils.format("{}/{}?download=0", uploadPath, path);
    }

    @Override
    public Map<String, Object> chunksCheck(String path, String name, String hash, Integer fileSize, Integer total) {
        throw new StorageException("暂未实现该功能");
    }

    @Override
    public Map<String, Object> chunksUpload(MultipartFile file, String path, String hash, String uploadId, Integer index, String fileSize) {
        throw new StorageException("暂未实现该功能");
    }

    @Override
    public Map<String, Object> chunksMerge(String path, String name, String hash, String uploadId, String fileSize) {
        throw new StorageException("暂未实现该功能");
    }
}
