package xtools.boot.storage.file.service.impl;

import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import xtools.base.config.BaseParams;
import xtools.boot.api.exection.BizError;
import xtools.boot.storage.base.config.StorageConfig;
import xtools.boot.storage.base.service.StorageService;
import xtools.core.FileUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * <p>Title : StorageServiceS3Impl</p>
 * <p>Description : StorageServiceS3Impl</p>
 * <p>DevelopTools : Idea_x64_v2026.1</p>
 * <p>DevelopSystem : macOS Sequoia 15.7.5</p>
 * <p>Company : org.xujun</p>
 *
 * @author : XuJun
 * @version : 5.0.0
 * @date : 2026/3/14 07:35
 */
@Slf4j
public class StorageServiceFileImpl implements StorageService, BaseParams {

    @Resource
    private StorageConfig storageConfig;

    /**
     * 是否存在文件
     *
     * @param bucket   桶
     * @param fileName 文件名
     * @return true or false
     */
    @Override
    public boolean exists(
            @NotNull String bucket,
            @NotNull String fileName
    ) {
        initBucket(bucket);
        File file = new File(getFilePath(bucket, fileName));
        return file.exists();
    }

    /**
     * 保存文件
     *
     * @param bucket        桶
     * @param fileName      文件名
     * @param inputStream   输入流
     * @param contentLength 文件长度
     */
    @Override
    public void save(
            @NotNull String bucket,
            @NotNull String fileName,
            @NotNull InputStream inputStream,
            long contentLength
    ) {
        initBucket(bucket);
        File file = new File(getFilePath(bucket, fileName));
        try (OutputStream outputStream = new FileOutputStream(file)) {
            byte[] bytes = new byte[CP_NUM1024];
            int len;
            while ((len = inputStream.read(bytes)) != CP_NEGATIVE1) {
                outputStream.write(bytes, CP_NUM0, len);
            }
        } catch (Exception e) {
            log.error("保存文件失败", e);
            throw new BizError("保存文件失败");
        }
    }

    /**
     * 获取文件
     *
     * @param bucket       桶
     * @param fileName     文件名
     * @param outputStream 输出流
     */
    @Override
    public void get(
            @NotNull String bucket,
            @NotNull String fileName,
            @NotNull OutputStream outputStream
    ) {
        initBucket(bucket);
        try (InputStream inputStream = new FileInputStream(getFilePath(bucket, fileName))) {
            byte[] bytes = new byte[CP_NUM1024];
            int len;
            while ((len = inputStream.read(bytes)) != CP_NEGATIVE1) {
                outputStream.write(bytes, CP_NUM0, len);
            }
        } catch (Exception e) {
            log.error("获取文件失败", e);
            throw new BizError("获取文件失败");
        }
    }

    /**
     * 删除文件
     *
     * @param bucket   桶
     * @param fileName 文件名
     */
    @Override
    public void del(
            @NotNull String bucket,
            @NotNull String fileName
    ) {
        initBucket(bucket);
        FileUtils.del(getFilePath(bucket, fileName));
    }

    /**
     * 初始化桶
     *
     * @param bucket 桶
     */
    private void initBucket(String bucket) {
        String path = getPath(bucket);
        File file = new File(path);
        if (file.exists()) {
            return;
        }
        if (file.mkdirs()) {
            return;
        }
        throw new BizError("创建目录失败" + path);
    }

    /**
     * 获取路径
     *
     * @param bucket 桶
     * @return 路径
     */
    private String getPath(String bucket) {
        return storageConfig.getFile().getPath() + CP_SLASH + bucket;
    }

    /**
     * 获取文件路径
     *
     * @param bucket   桶
     * @param fileName 文件名
     * @return 文件路径
     */
    private String getFilePath(String bucket, String fileName) {
        return getPath(bucket) + CP_SLASH + fileName;
    }
}
