package cn.reghao.tnb.file.app.zoss.rpc;

import cn.reghao.tnb.oss.api.dto.disk.DiskVolume;
import cn.reghao.tnb.oss.api.iface.StoreService;
import cn.reghao.tnb.oss.api.dto.ObjectInfo;
import cn.reghao.tnb.oss.api.dto.media.AudioInfo;
import cn.reghao.tnb.oss.api.dto.media.ConvertedImageInfo;
import cn.reghao.tnb.oss.api.dto.media.ImageInfo;
import cn.reghao.tnb.oss.api.dto.media.VideoInfo;
import cn.reghao.tnb.file.app.zoss.db.mapper.StoreNodeMapper;
import cn.reghao.tnb.file.app.zoss.model.po.StoreNode;
import cn.reghao.tnb.file.app.zoss.service.UserNodeService;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 对 oss-store 进行操作
 * 第三方通过 oss-console 调用
 *
 * @author reghao
 * @date 2024-04-23 15:14:06
 */
@Service
public class StoreServiceWrapper {
    private final RpcService rpcService;
    private final UserNodeService userNodeService;
    private final StoreNodeMapper storeNodeMapper;

    public StoreServiceWrapper(RpcService rpcService, UserNodeService userNodeService, StoreNodeMapper storeNodeMapper) {
        this.rpcService = rpcService;
        this.userNodeService = userNodeService;
        this.storeNodeMapper = storeNodeMapper;
    }

    private StoreService getStoreService(int channelCode, int owner) throws Exception {
        StoreNode storeNode = userNodeService.getStoreNodeByChannel(channelCode, owner);
        if (storeNode == null) {
            String errMsg = String.format("channel_code %s not associate with any store_node", channelCode);
            throw new Exception(errMsg);
        }

        return rpcService.getStoreService(storeNode);
    }

    public void createChannel(int userNodeId, String channelPrefix, int scope, int owner) throws Exception {
        StoreNode storeNode = userNodeService.getStoreNode(userNodeId);
        StoreService storeService = rpcService.getStoreService(storeNode);
        storeService.createChannel(owner, channelPrefix, scope);
    }

    public Integer countChannelObjects(int channelCode, String channelPrefix, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        return storeService.countChannelObjects(channelPrefix, owner);
    }

    public List<DiskVolume> getDiskVolumes(int storeNodeId) {
        StoreNode storeNode = storeNodeMapper.findById(storeNodeId);
        StoreService storeService = rpcService.getStoreService(storeNode);
        return storeService.getDiskVolumes();
    }

    public void setObjectUpload(int channelCode, String objectId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        storeService.setObjectUpload(objectId);
    }

    public void setObjectScope(int channelCode, String objectId, int scope, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        storeService.setObjectScope(objectId, scope);
    }

    public void deleteByObjectId(int channelCode, String objectId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        storeService.deleteByObjectId(objectId);
    }

    public void deleteByObjectName(int channelCode, String objectName, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        storeService.deleteByObjectName(objectName, owner);
    }

    public void deleteByObjectUrl(String objectUrl, int owner) {
        String domain = objectUrl.replace("//", "").split("/")[0];
        String objectName = objectUrl.replace("//" + domain + "/", "");
        StoreNode storeNode = userNodeService.getStoreNodeByDomain(domain);
        StoreService storeService = rpcService.getStoreService(storeNode);
        storeService.deleteByObjectName(objectName, owner);
    }

    public ObjectInfo getObjectInfo(int channelCode, String objectId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        ObjectInfo objectInfo = storeService.getObjectInfo(objectId);
        String domain = userNodeService.getDomain(channelCode, owner);
        String url = String.format("//%s/%s", domain, objectInfo.getUrl());
        objectInfo.setUrl(url);
        return objectInfo;
    }

    public String getSignedUrl(int channelCode, String objectId, int owner) throws Exception {
        String domain = userNodeService.getDomain(channelCode, owner);
        StoreService storeService = getStoreService(channelCode, owner);
        // url 有效期为 24h
        int expire = 3600*24;
        String signedUrl = storeService.getSignedUrl(domain, owner, objectId, expire);
        return signedUrl;
    }

    public String getSignedUrlByUrl(int channelCode, String objectUrl, int owner) throws Exception {
        String domain = userNodeService.getDomain(channelCode, owner);
        StoreService storeService = getStoreService(channelCode, owner);
        // url 有效期为 24h
        int expire = 3600*24;
        String signedUrl = storeService.getSignedUrl(objectUrl, owner, expire);
        return signedUrl;
    }

    public VideoInfo getVideoInfo(int channelCode, String videoFileId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        VideoInfo videoInfo = storeService.getVideoInfo(videoFileId);
        String domain = userNodeService.getDomain(channelCode, owner);
        String url = String.format("//%s/%s", domain, videoInfo.getUrl());
        videoInfo.setUrl(url);
        return videoInfo;
    }

    public ImageInfo getImageInfo(int channelCode, String imageFileId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        ImageInfo imageInfo = storeService.getImageInfo(imageFileId);
        String domain = userNodeService.getDomain(channelCode, owner);
        String url = String.format("//%s/%s", domain, imageInfo.getUrl());
        imageInfo.setUrl(url);
        return imageInfo;
    }

    public ConvertedImageInfo getWebpInfo(int channelCode, String imageFileId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        ConvertedImageInfo convertedImageInfo = storeService.getWebpInfo(imageFileId);
        String domain = userNodeService.getDomain(channelCode, owner);
        String url = String.format("//%s/%s", domain, convertedImageInfo.getUrl());
        convertedImageInfo.setUrl(url);
        return convertedImageInfo;
    }

    public AudioInfo getAudioInfo(int channelCode, String audioFileId, int owner) throws Exception {
        StoreService storeService = getStoreService(channelCode, owner);
        AudioInfo audioInfo = storeService.getAudioInfo(audioFileId);
        String domain = userNodeService.getDomain(channelCode, owner);
        String url = String.format("//%s/%s", domain, audioInfo.getUrl());
        audioInfo.setUrl(url);
        return audioInfo;
    }
}
