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

import com.qmth.boot.core.exception.StatusException;
import com.qmth.boot.core.fss.store.FileStore;
import com.qmth.boot.tools.io.IOUtils;
import com.qmth.boot.tools.models.ByteArray;
import com.qmth.boot.tools.uuid.FastUUID;

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

/**
 * 本地磁盘文件管理工具
 */
public class DiskStore implements FileStore {

    private String server;

    private File rootDir;

    private File tempDir;

    public DiskStore(String server, String path, String temp) {
        this.server = server;
        this.rootDir = new File(path);
        this.tempDir = new File(temp);
        if (!rootDir.exists() && !rootDir.mkdirs()) {
            //自动创建目录失败
            throw new IllegalArgumentException("Fss disk store: " + path + ": auto mkdir faile");
        } else if (rootDir.isFile()) {
            //判断是否不是目录
            throw new IllegalArgumentException("Fss disk store: " + path + ": is a file");
        }
        if (!tempDir.exists() && !tempDir.mkdirs()) {
            //自动创建目录失败
            throw new IllegalArgumentException("Fss disk store: temp auto mkdir faile");
        } else if (tempDir.isFile()) {
            //判断是否不是目录
            throw new IllegalArgumentException("Fss disk store: temp dir is a file");
        }
    }

    @Override
    public String getServer() {
        return server;
    }

    @Override
    public void write(String path, InputStream ins, String md5) throws Exception {
        path = formatPath(path);
        //临时目录创建临时文件
        File tempFile = new File(tempDir, FastUUID.get());
        try {
            //final MessageDigest digest = CodecUtils.getMd5();
            FileOutputStream ous = new FileOutputStream(tempFile);
            IOUtils.copy(ins, ous);
            //IOUtils.copy(ins, ous, (buffer, length) -> digest.update(buffer, 0, length));
            //校验写入内容的摘要信息
            //if (!CodecUtils.toBase64(digest.digest()).equalsIgnoreCase(toBase64(md5))) {
            //throw new RuntimeException("Write md5 validate faile");
            //}
            IOUtils.closeQuietly(ins);
            IOUtils.closeQuietly(ous);
            //校验写入内容的摘要信息
            if (!ByteArray.md5(tempFile).toBase64().equalsIgnoreCase(toBase64(md5))) {
                throw new RuntimeException("Write md5 validate faile");
            }
            //检查正式文件及目录
            File targetFile = new File(rootDir, path);
            if (targetFile.isDirectory()) {
                throw new RuntimeException("Target file is directory: " + path);
            }
            targetFile.getParentFile().mkdirs();
            //临时文件拷贝到正式文件
            IOUtils.copy(tempFile, targetFile);
        } finally {
            tempFile.delete();
        }
    }

    @Override
    public InputStream read(String path) throws Exception {
        path = formatPath(path);
        File file = new File(rootDir, path);
        if (file.exists() && file.isFile()) {
            return new FileInputStream(file);
        } else {
            throw new RuntimeException("Read file unexist:" + path);
        }
    }

    @Override
    public boolean exist(String path) {
        path = formatPath(path);
        File file = new File(rootDir, path);
        return file.exists() && file.isFile();
    }

    @Override
    public boolean delete(String path) {
        path = formatPath(path);
        File file = new File(rootDir, path);
        if (file.exists() && file.isFile()) {
            return file.delete();
        } else {
            throw new StatusException(path + " not exist");
        }
    }

    @Override
    public void copy(String source, String target) throws Exception {
        source = formatPath(source);
        target = formatPath(target);
        IOUtils.copy(new File(rootDir, source), new File(rootDir, target));
    }

}
