package cn.reghao.oss.store.service;

import cn.reghao.oss.store.db.repository.ObjectRepository;
import cn.reghao.oss.store.model.po.DataBlock;
import cn.reghao.oss.store.model.po.FileMeta;
import cn.reghao.oss.store.model.vo.ObjectProp;
import cn.reghao.oss.store.model.vo.ObjectResult;
import cn.reghao.oss.store.util.FileType;
import cn.reghao.oss.store.util.StringUtil;
import cn.reghao.oss.api.dto.ObjectMeta;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.List;
import java.util.UUID;

/**
 * @author reghao
 * @date 2023-05-10 13:28:18
 */
@Slf4j
@Service
public class PutObjectService {
    private final ObjectRepository objectRepository;
    private final ObjectNameService objectNameService;

    public PutObjectService(ObjectRepository objectRepository, ObjectNameService objectNameService) {
        this.objectRepository = objectRepository;
        this.objectNameService = objectNameService;
    }

    public ObjectResult putObject(ObjectProp objectProp, String contentId, File savedFile, String originalFilename, String sha256sum) {
        String pid = objectProp.getPid();
        String objectName = objectProp.getObjectName();
        FileMeta fileMeta = objectRepository.getBySha256sum(sha256sum);
        if (fileMeta != null) {
            FileUtils.deleteQuietly(savedFile);
            return copyObject(objectProp, originalFilename, fileMeta);
        } else {
            String savedPath = savedFile.getAbsolutePath();
            long size = savedFile.length();
            String objectId = UUID.randomUUID().toString().replace("-", "");
            String contentType = FileType.getMediaType(savedPath);
            int fileType = FileType.getFileType(contentType);

            boolean diskFile = objectProp.isDiskFile();
            int scope = objectProp.getScope();
            fileMeta = new FileMeta(objectName, objectId, contentId, originalFilename, size,
                    fileType, contentType, sha256sum, pid, diskFile, scope);
            String blockId = UUID.randomUUID().toString();
            List<DataBlock> list = List.of(new DataBlock(contentId, 0, blockId, savedPath, size));
            objectRepository.saveObject(fileMeta, list);
            return new ObjectResult(objectName, objectId, fileType, savedPath);
        }
    }

    public void putObject(String objectName, byte[] bytes) {
    }

    public ObjectResult copyObject(ObjectProp objectProp, String filename, FileMeta fileMeta) {
        String dupObjectId = fileMeta.getObjectId();
        ObjectMeta objectMeta = objectRepository.getObjectMeta(fileMeta.getObjectName());

        int fileType = fileMeta.getFileType();
        String savedPath = objectMeta.getAbsolutePath();
        String objectName = objectProp.getObjectName();
        String objectId = UUID.randomUUID().toString().replace("-", "");
        boolean diskFile = objectProp.isDiskFile();
        int scope = objectProp.getScope();
        FileMeta fileMeta1 = new FileMeta(objectName, objectId, filename, fileMeta, diskFile, scope);
        objectRepository.saveFileMeta(fileMeta1);
        return new ObjectResult(objectName, objectId, fileType, savedPath, dupObjectId);
    }

    public ObjectResult copyFromObjectName(String fromObjectName) {
        FileMeta fileMeta = objectRepository.getByObjectName(fromObjectName);
        int fileType = fileMeta.getFileType();

        String suffix = StringUtil.getSuffix(fromObjectName);
        String filename = fileMeta.getFilename();
        String savedPath = "";
        boolean diskFile = fileMeta.getDiskFile();
        int scope = fileMeta.getScope();
        String toObjectName = objectNameService.getObjectNameFromOriginal(fromObjectName, suffix);
        String toObjectId = UUID.randomUUID().toString().replace("-", "");
        FileMeta fileMeta1 = new FileMeta(toObjectName, toObjectId, filename, fileMeta, diskFile, scope);
        objectRepository.saveFileMeta(fileMeta1);
        return new ObjectResult(toObjectName, toObjectId, fileType, savedPath);
    }

    public ObjectResult copyFromObjectId(String fromObjectId) {
        FileMeta fileMeta = objectRepository.getByObjectId(fromObjectId);
        int fileType = fileMeta.getFileType();

        String fromObjectName = fileMeta.getObjectName();
        String suffix = StringUtil.getSuffix(fromObjectName);
        String filename = fileMeta.getFilename();
        String savedPath = "";
        boolean diskFile = fileMeta.getDiskFile();
        int scope = fileMeta.getScope();
        String toObjectName = objectNameService.getObjectNameFromOriginal(fromObjectName, suffix);
        String toObjectId = UUID.randomUUID().toString().replace("-", "");
        FileMeta fileMeta1 = new FileMeta(toObjectName, toObjectId, filename, fileMeta, diskFile, scope);
        objectRepository.saveFileMeta(fileMeta1);
        return new ObjectResult(toObjectName, toObjectId, fileType, savedPath);
    }

    public void deleteObject(String objectId) {
        objectRepository.deleteByObjectIds(List.of(objectId));
    }
}
