package com.philisense.www.cloud;

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.upyun.RestManager;
import okhttp3.Response;
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.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * Upyun 文件存储
 * 
 */
public class UpyunStorageService extends OssStorageService {

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

    private OssStorageProperties.UpyunConfig upyunConfig;
    private String diskName;

    private RestManager restManager;

    private OssRule ossRule;

    public UpyunStorageService(OssStorageProperties.UpyunConfig upyunConfig, String diskName) {
        this.upyunConfig = upyunConfig;
        this.diskName = diskName;
        ossRule = SpringContextUtils.getBean(OssRule.class);
        restManager = new RestManager(upyunConfig.getBucketName(), upyunConfig.getUserName(), upyunConfig.getPassword());
    }

    @Override
    public Map<String, Object> upload(MultipartFile file, String path) {
        try {
            return put(file.getInputStream(), path);
        } catch (Exception e) {
            log.error("上传文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("上传文件失败", e);
        }
    }

    @Override
    public Map<String, Object> upload(byte[] data, String path) {
        return put(new ByteArrayInputStream(data), path);
    }

    private Map<String, Object> put(InputStream stream, String path) {
        try {
            path = ossRule.filePath(diskName + FileUtils.SLASH + path);
            Response response = restManager.writeFile(path, stream, null);
            int retry = 0;
            int retryCount = 5;
            while (!response.isSuccessful() && retry < retryCount) {
                response = restManager.writeFile(path, stream, null);
                retry++;
            }

            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 InputStream download(String path) {
        try {
            Response res = restManager.readFile(path);
            if (!res.isSuccessful()) {
                throw new StorageException("下载文件失败：" + res.toString());
            }
            return res.body().byteStream();
        } catch (Exception e) {
            log.error("下载文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("下载文件失败", e);
        }
    }

    @Override
    public void delete(String path) {
        try {
            Response res = restManager.deleteFile(path, null);
            restManager.rmDir(StorageUtils.getFilePath(path));
            if (!res.isSuccessful()) {
                throw new StorageException("删除文件失败：" + res.toString());
            }
        } catch (Exception e) {
            log.error("删除文件失败：{} | {}",e.getMessage(), e);
            throw new StorageException("删除文件失败", e);
        }
    }

    @Override
    public String getUrl(String path) {
        return upyunConfig.getEndpoint().concat(String.valueOf(FileUtils.SLASH)).concat(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("暂未实现该功能");
    }
}
