package cn.reghao.oss.console.app.rpc;

import cn.reghao.oss.api.dto.ObjectInfo;
import cn.reghao.oss.api.dto.StoreInfo;
import cn.reghao.oss.api.dto.media.AudioInfo;
import cn.reghao.oss.api.dto.media.ConvertedImageInfo;
import cn.reghao.oss.api.dto.media.ImageInfo;
import cn.reghao.oss.api.dto.media.VideoInfo;
import cn.reghao.oss.api.iface.StoreService;
import cn.reghao.oss.api.iface.StoreServiceWrapper;
import cn.reghao.oss.api.util.AuthContext;
import cn.reghao.oss.console.app.model.po.StoreNode;
import cn.reghao.oss.console.app.model.po.UploadChannel;
import cn.reghao.oss.console.app.service.UploadChannelService;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author reghao
 * @date 2024-07-03 14:40:25
 */
@Service
public class StoreServiceWrapperImpl implements StoreServiceWrapper {
    private final UploadChannelService uploadChannelService;

    public StoreServiceWrapperImpl(UploadChannelService uploadChannelService) {
        this.uploadChannelService = uploadChannelService;
    }

    @Override
    public int getChannelScope(int channelId) {
        return -1;
    }

    private StoreService getStoreService(int channelId) throws Exception {
        int loginUser = 1;
        StoreNode storeNode = uploadChannelService.getStoreNodeByChannelId(loginUser, channelId);
        if (storeNode == null) {
            String errMsg = String.format("channel_id %s not associate with any store_node", channelId);
            throw new Exception(errMsg);
        }

        return getStoreService(storeNode);
    }

    public StoreService getStoreService(StoreNode storeNode) {
        RemoteService<StoreService> remoteService = new RemoteService<>();
        String host = storeNode.getNodeAddr();
        int port = storeNode.getRpcPort();
        return remoteService.getService(host, port, StoreService.class);
    }

    @Override
    public void createChannel(int channelId, String channelPrefix) {
        try {
            StoreService storeService = getStoreService(channelId);
            storeService.createChannel(channelPrefix);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public StoreInfo getStoreInfo(int channelId) {
        try {
            StoreService storeService = getStoreService(channelId);
            return storeService.getStoreInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public void setObjectScope(int channelId, String objectId, int scope) {
        try {
            StoreService storeService = getStoreService(channelId);
            storeService.setObjectScope(objectId, scope);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteByObjectId(int channelId, String objectId) {
        try {
            StoreService storeService = getStoreService(channelId);
            storeService.deleteByObjectId(objectId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteByObjectUrl(String objectUrl) {
        int loginUser = AuthContext.getUserId();
        String domain = objectUrl.replace("//", "").split("/")[0];
        String objectName = objectUrl.replace("//" + domain + "/", "");
        List<UploadChannel> uploadChannels = uploadChannelService.getByDomainAndCreateBy(domain, loginUser);
        for (UploadChannel uploadChannel : uploadChannels) {
            String prefix = uploadChannel.getPrefix();
            // TODO get best match
            if (objectName.startsWith(prefix)) {
                int channelId = uploadChannel.getChannelId();
                try {
                    StoreService storeService = getStoreService(channelId);
                    storeService.deleteByObjectUrl(objectName);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public ObjectInfo getObjectInfo(int channelId, String objectId) {
        try {
            StoreService storeService = getStoreService(channelId);
            int loginUser = AuthContext.getUserId();
            int expireSecond = 3600;
            return storeService.getObjectInfo(objectId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public String getSignedUrl(int channelId, String objectId) {
        try {
            StoreService storeService = getStoreService(channelId);
            return storeService.getSignedUrl(objectId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public VideoInfo getVideoInfo(int channelId, String videoFileId) {
        try {
            StoreService storeService = getStoreService(channelId);
            return storeService.getVideoInfo(videoFileId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public ImageInfo getImageInfo(int channelId, String imageFileId) {
        try {
            StoreService storeService = getStoreService(channelId);
            return storeService.getImageInfo(imageFileId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public ConvertedImageInfo getWebpInfo(int channelId, String imageFileId) {
        try {
            int loginUser = AuthContext.getUserId();
            StoreService storeService = getStoreService(channelId);
            return storeService.getWebpInfo(imageFileId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public AudioInfo getAudioInfo(int channelId, String audioFileId) {
        try {
            StoreService storeService = getStoreService(channelId);
            return storeService.getAudioInfo(audioFileId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
