package cn.reghao.oss.store.rpc.disk;

import cn.reghao.oss.store.api.constant.ObjectScope;
import cn.reghao.oss.store.api.dto.DirProp;
import cn.reghao.oss.store.api.dto.FileProp;
import cn.reghao.oss.store.api.iface.disk.FileService;
import cn.reghao.oss.store.db.mapper.FileMetaMapper;
import cn.reghao.oss.store.model.po.FileMeta;
import cn.reghao.oss.store.service.PutObjectService;
import cn.reghao.oss.store.service.StoreLocalCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

/**
 * @author reghao
 * @date 2023-05-18 20:39:45
 */
@Slf4j
@DubboService
@Service
public class FileServiceImpl implements FileService {
    private final PutObjectService putObjectService;
    private final FileMetaMapper fileMetaMapper;
    private final StoreLocalCache storeLocalCache;

    public FileServiceImpl(PutObjectService putObjectService, FileMetaMapper fileMetaMapper, StoreLocalCache storeLocalCache) {
        this.fileMetaMapper = fileMetaMapper;
        this.putObjectService = putObjectService;
        this.storeLocalCache = storeLocalCache;
    }

    @Override
    public String checkFilename(String pid, String filename) {
        List<FileMeta> list = fileMetaMapper.findByFilename(pid, filename);
        if (!list.isEmpty()) {
            filename += list.size();
        }
        return filename;
    }

    @Override
    public void createDirectory(String pid, String filename) {
        String filename1 = checkFilename(pid, filename);
        String fileId = UUID.randomUUID().toString().replace("-", "");
        String objectName = String.format("disk/0/1/%s/", fileId);
        FileMeta fileMeta = new FileMeta(objectName, fileId, filename1, pid, ObjectScope.PRIVATE.getCode());
        fileMetaMapper.save(fileMeta);
    }

    @Override
    public String createFile(String pid, String filename, String content) {
        String fileId = UUID.randomUUID().toString().replace("-", "");
        String objectName = "";
        byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
        putObjectService.putObject(objectName, bytes);
        return fileId;
    }

    @Override
    public void copyFile(List<String> fileIds, String toPid) {
        List<FileMeta> list = fileMetaMapper.findFileInfos(fileIds);
    }

    @Override
    public void moveFile(List<String> fileIds, String toPid) {
        List<FileMeta> list = fileMetaMapper.findFileInfos(fileIds);
        list.forEach(fileInfo -> {
            fileMetaMapper.updateParent(fileInfo.getObjectId(), toPid);
        });
    }

    @Override
    public void renameFile(String fileId, String newFilename) {
        FileMeta fileMeta = fileMetaMapper.findByObjectId(fileId);
        String pid = fileMeta.getPid();
        String filename1 = checkFilename(pid, newFilename);
        fileMetaMapper.updateFilename(fileId, filename1);
    }

    @Override
    public void deleteFiles(List<String> fileIds) {
    }

    @Override
    public FileProp getFileProp(String fileId) {
        FileMeta fileMeta = fileMetaMapper.findByObjectId(fileId);
        String pid = fileMeta.getPid();
        String path = "";

        String filename = fileMeta.getFilename();
        long size = fileMeta.getSize();
        String contentType = fileMeta.getContentType();
        String sha256sum = fileMeta.getSha256sum();
        String url = String.format("https://%s/%s", storeLocalCache.getDomain(), fileMeta.getObjectName());
        return new FileProp(path, filename, size, contentType, sha256sum, url);
    }

    @Override
    public DirProp getDirProp(String fileId) {
        // 当前目录下的文件和子目录
        List<FileMeta> list = fileMetaMapper.findByPid(fileId);
        DirProp dirProp = getDirProp(list);
        return dirProp;
    }

    private DirProp getDirProp(List<FileMeta> list) {
        long totalSize = 0;
        long totalDirs = list.stream().filter(fileInfo -> fileInfo.getFileType() == 1000).count();
        long totalFiles = list.stream().filter(fileInfo -> fileInfo.getFileType() != 1000).count();
        for (FileMeta fileMeta : list) {
            int fileType = fileMeta.getFileType();
            if (fileType != 1000) {
                totalSize += fileMeta.getSize();
            } else {
                // getDirProp(fileInfo.getFileId());
            }
        }
        return new DirProp(totalDirs, totalFiles, totalSize);
    }
}
