package com.qmth.boot.core.fss.store;

import com.qmth.boot.core.fss.utils.FssUtils;
import com.qmth.boot.tools.models.ByteArray;
import org.apache.commons.lang3.StringUtils;

import java.io.InputStream;
import java.time.Duration;

/**
 * 通用文件存储服务
 */
public interface FileStore {

    /**
     * 关闭服务
     */
    default void close() {
    }

    /**
     * 将md5内容转换为hexString格式
     *
     * @param md5
     * @return
     */
    default String toHexString(String md5) {
        if (StringUtils.isBlank(md5)) {
            throw new IllegalArgumentException("Invalid md5 parameter");
        }
        //hex格式
        if (md5.length() == 32) {
            return md5;
        }
        //base64格式
        else if (md5.length() == 24) {
            return ByteArray.fromBase64(md5).toHexString();
        }
        throw new IllegalArgumentException("Invalid md5 length");
    }

    /**
     * 将md5内容转换为base64格式
     *
     * @param md5
     * @return
     */
    default String toBase64(String md5) {
        if (StringUtils.isBlank(md5)) {
            throw new IllegalArgumentException("Invalid md5 parameter");
        }
        //hex格式
        if (md5.length() == 32) {
            return ByteArray.fromHexString(md5).toBase64();
        }
        //base64格式
        else if (md5.length() == 24) {
            return md5;
        }
        throw new IllegalArgumentException("Invalid md5 length");
    }

    /**
     * 自动预处理path，去掉开头的分隔符并判空
     *
     * @param path
     * @return
     */
    default String formatPath(String path) {
        path = StringUtils.trimToNull(path);
        if (path == null) {
            throw new IllegalArgumentException("Invalid path parameter");
        }
        if (path.startsWith(FssUtils.FILE_PATH_SEPARATOR)) {
            path = path.substring(1);
        }
        return path;
    }

    /**
     * 获取临时授权访问URL
     *
     * @param path
     * @param expireDuration
     * @return
     */
    default String getPresignedUrl(String path, Duration expireDuration) {
        return getServer().concat(formatPath(path));
    }

    /**
     * 获取公开访问URL前缀
     *
     * @return
     */
    String getServer();

    /**
     * 从输入流读取内容写入到文件存储的指定位置，强制进行md5校验
     *
     * @param path
     * @param ins
     * @param md5
     * @throws Exception
     */
    void write(String path, InputStream ins, String md5) throws Exception;

    /**
     * 从文件存储的指定位置读取文件流，用完后需要手动关闭
     *
     * @param path
     * @return
     * @throws Exception
     */
    InputStream read(String path) throws Exception;

    /**
     * 判断文件存储中指定文件是否存在
     *
     * @param path
     * @return
     */
    boolean exist(String path);

    /**
     * 删除已存在的文件
     *
     * @param path
     */
    boolean delete(String path);

    /**
     * 将指定路径的文件复制到目标路径中
     *
     * @param source
     * @param target
     */
    void copy(String source, String target) throws Exception;
}
