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

import cn.reghao.tnb.oss.api.dto.NodeProperties;
import cn.reghao.tnb.oss.api.dto.ObjectChannel;
import cn.reghao.tnb.oss.api.dto.StoreNodeDto;
import cn.reghao.tnb.oss.api.iface.ConsoleService;
import cn.reghao.tnb.oss.api.iface.StoreService;
import cn.reghao.tnb.oss.api.dto.ServerInfo;
import cn.reghao.tnb.file.app.zoss.model.po.StoreNode;
import cn.reghao.tnb.file.app.zoss.model.po.UploadChannel;
import cn.reghao.tnb.file.app.zoss.model.po.UserNode;
import cn.reghao.tnb.file.app.service.StoreConfigService;
import cn.reghao.tnb.file.app.zoss.service.StoreNodeService;
import cn.reghao.tnb.file.app.zoss.service.UploadChannelService;
import cn.reghao.tnb.file.app.zoss.service.UserNodeService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author reghao
 * @date 2024-07-02 10:58:51
 */
@DubboService
@Service
public class ConsoleServiceImpl implements ConsoleService {
    private final UploadChannelService uploadChannelService;
    private final StoreNodeService storeNodeService;
    private final UserNodeService userNodeService;
    private final RpcService rpcService;
    private final StoreConfigService storeConfigService;

    public ConsoleServiceImpl(UploadChannelService uploadChannelService, StoreNodeService storeNodeService,
                              UserNodeService userNodeService, RpcService rpcService, StoreConfigService storeConfigService) {
        this.uploadChannelService = uploadChannelService;
        this.storeNodeService = storeNodeService;
        this.userNodeService = userNodeService;
        this.rpcService = rpcService;
        this.storeConfigService = storeConfigService;
    }

    @Override
    public void registerNode(StoreNodeDto storeNodeDto) {
        storeNodeService.addOrUpdate(storeNodeDto);
    }

    @Override
    public NodeProperties getNodeProperties(String domain) {
        UserNode userNode = userNodeService.getUserNodeByDomain(domain);
        if (userNode != null) {
            String secretKey = userNode.getDomain();
            String referer = userNode.getReferer();
            long owner = userNode.getCreateBy();
            return new NodeProperties(domain, secretKey, referer, (int) owner);
        }

        return null;
    }

    @Override
    public ObjectChannel getChannelByCode(int owner, int channelCode) {
        return uploadChannelService.getObjectChannelByChannelCode(channelCode, owner);
    }

    @Override
    public Integer getChannelCodeByUrl(int owner, String url) {
        List<UploadChannel> uploadChannels = uploadChannelService.getUploadChannelsByCreateBy(owner);
        String url1 = url.replace("//", "");
        int idx = url1.indexOf("/");
        String objectName = url1.substring(idx+1);
        for (UploadChannel uploadChannel : uploadChannels) {
            if (objectName.startsWith(uploadChannel.getPrefix())) {
                return uploadChannel.getChannelCode();
            }
        }

        return -1;
    }

    @Override
    public ServerInfo getUploadStore(int channelCode) {
        int ossUser = storeConfigService.getLocalOssUser();
        UploadChannel uploadChannel = uploadChannelService.getByChannelCodeAndCreateBy(channelCode, ossUser);
        if (uploadChannel == null) {
            String errMsg = String.format("channelCode %s not exist", channelCode);
            return null;
        }

        UserNode userNode = userNodeService.getUserNode(uploadChannel.getUserNodeId());
        if (userNode == null) {
            String errMsg = String.format("channel_code %s not associate with any store_node", uploadChannel.getId());
            return null;
        }

        String protocol = userNode.getProtocol();
        String domain = userNode.getDomain();
        String ossUrl = String.format("%s://%s", protocol, domain);
        long maxSize = uploadChannel.getMaxSize();

        try {
            StoreNode storeNode = storeNodeService.getByStoreNodeId(userNode.getStoreNodeId());
            StoreService storeService = rpcService.getStoreService(storeNode);

            // 多少秒后 token 过期
            int expire = 3600;
            String uploadToken = storeService.getUploadToken(channelCode, ossUser, expire);
            return new ServerInfo(ossUrl, channelCode, maxSize, uploadToken);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }
}
