package cn.reghao.oss.store.service;

import cn.reghao.oss.store.config.OssProperties;
import cn.reghao.oss.store.db.repository.ObjectRepository;
import cn.reghao.oss.store.model.po.FileMeta;
import cn.reghao.oss.store.model.vo.ObjectProp;
import cn.reghao.oss.store.util.StringUtil;
import cn.reghao.oss.api.constant.ObjectScope;
import cn.reghao.oss.api.constant.UploadChannel;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author reghao
 * @date 2023-06-02 16:22:50
 */
@Service
public class ObjectNameService {
    private final ObjectRepository objectRepository;
    private final String domain;

    public ObjectNameService(ObjectRepository objectRepository, OssProperties ossProperties) {
        this.objectRepository = objectRepository;
        this.domain = ossProperties.getDomain();
    }

    public String getObjectUrl(String objectName) {
        return String.format("//%s/%s", domain, objectName);
    }

    public String getObjectNameFromUrl(String url) {
        return url.replace(String.format("//%s/", domain), "");
    }

    public ObjectProp getObjectProp(int channelId, String filename) throws Exception {
        String suffix = StringUtil.getSuffix(filename);
        UploadChannel channel = UploadChannel.getUploadChannel(channelId);
        if (channel == null) {
            throw new Exception("channelId 不合法");
        }

        String objectPrefix = channel.getPrefix();
        String objectName = objectPrefix + UUID.randomUUID().toString().replace("-", "") + suffix;
        boolean diskFile = channelId == UploadChannel.disk.getCode();
        int scope = ObjectScope.PRIVATE.getCode();
        if (channelId == UploadChannel.avatar.getCode() || channelId == UploadChannel.image.getCode()) {
            scope = ObjectScope.PUBLIC.getCode();
        }

        FileMeta fileMeta = objectRepository.getByObjectName(objectPrefix);
        if (fileMeta == null) {
            String errMsg = String.format("objectPrefix %s 不合法", objectPrefix);
            throw new Exception(errMsg);
        }

        String pid = fileMeta.getObjectId();
        return new ObjectProp(objectName, diskFile, scope, pid);
    }

    public ObjectProp getObjectProp(String originalObjectName, String suffix) {
        int idx = originalObjectName.lastIndexOf("/");
        String prefix = originalObjectName.substring(0, idx+1);
        UploadChannel channel = UploadChannel.getUploadChannel(prefix);
        FileMeta fileMeta = objectRepository.getByObjectName(originalObjectName);
        boolean diskFile = fileMeta.getDiskFile();
        int scope = fileMeta.getScope();
        String pid = fileMeta.getPid();

        String objectPrefix = channel.getPrefix();
        String objectName = objectPrefix + UUID.randomUUID().toString().replace("-", "") + suffix;
        return new ObjectProp(objectName, diskFile, scope, pid);
    }

    public String getObjectNameFromOriginal(String originalObjectName, String suffix) {
        int idx = originalObjectName.lastIndexOf("/");
        String prefix = originalObjectName.substring(0, idx+1);
        String id = UUID.randomUUID().toString().replace("-", "");
        return prefix + id + suffix;
    }

    public void createParentDirs(String objectName, int scope) {
        List<String> list = getSortedParent(objectName);
        for (int i = 0; i < list.size(); i++) {
            String parentName = list.get(i);
            FileMeta fileMeta = objectRepository.getByObjectName(parentName);
            if (fileMeta == null) {
                String pid;
                if (i == 0) {
                    pid = "0";
                } else {
                    pid = objectRepository.getByObjectName(list.get(i-1)).getObjectId();
                }
                String objectId = UUID.randomUUID().toString().replace("-", "");
                String[] names = parentName.split("/");
                String filename = names[names.length-1];
                objectRepository.saveFileMeta(new FileMeta(parentName, objectId, filename, pid, scope));
            }
        }
    }

    private List<String> getSortedParent(String objectName) {
        String[] arr = objectName.split("/");
        List<String> list = new ArrayList<>();
        list.add(arr[0] + "/");
        for (int i = 1; i < arr.length; i++) {
            list.add(list.get(i-1) + arr[i] + "/");
        }
        return list;
    }
}
