package cn.reghao.oss.store.rpc;

import cn.reghao.jutil.media.ImageOps;
import cn.reghao.oss.api.dto.*;
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.service.ObjectNameService;
import cn.reghao.oss.store.util.JwtUtil;
import cn.reghao.oss.store.util.SignatureUtil;
import cn.reghao.oss.api.constant.ChannelAction;
import cn.reghao.oss.api.constant.UploadChannel;
import cn.reghao.oss.api.iface.ObjectService;
import cn.reghao.oss.store.db.mapper.FileMetaMapper;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * @author reghao
 * @date 2023-05-28 23:26:03
 */
@DubboService
@Service
public class ObjectServiceImpl implements ObjectService {
    private final FileMetaMapper fileMetaMapper;
    private final ObjectNameService objectNameService;
    private final ObjectRepository objectRepository;
    private final String secretKey;

    public ObjectServiceImpl(FileMetaMapper fileMetaMapper, ObjectNameService objectNameService,
                             ObjectRepository objectRepository, OssProperties ossProperties) {
        this.fileMetaMapper = fileMetaMapper;
        this.objectNameService = objectNameService;
        this.objectRepository = objectRepository;
        this.secretKey = ossProperties.getSecretKey();
    }

    @Override
    public void putObjectPrefix(ObjectPrefix objectPrefix) {
        String prefix = objectPrefix.getPrefix();
        int scope = objectPrefix.getScope();
        FileMeta fileMeta = fileMetaMapper.findByObjectName(prefix);
        if (fileMeta != null) {
            return;
        }
        objectNameService.createParentDirs(prefix, scope);
    }

    @Override
    public List<String> getObjectPrefix() {
        return fileMetaMapper.findObjectPrefix();
    }

    @Override
    public ObjectMeta getObject(String objectName) {
        return objectRepository.getObjectMeta(objectName);
    }

    @Override
    public DownloadUrl getDownloadUrl(String objectId, int channelId, long userId) {
        FileMeta fileMeta = objectRepository.getByObjectId(objectId);
        String objectName = fileMeta.getObjectName();
        String url = objectNameService.getObjectUrl(objectName);
        String signedUrl = getSignedUrl(url, userId);
        return new DownloadUrl(signedUrl, "");
    }

    private String getSignedUrl(String url, long loginUser) {
        String secretId = loginUser+"";
        long timestamp = System.currentTimeMillis() + 3600*1000;

        String action = ChannelAction.download.getName();
        OssPayload ossPayload = new OssPayload(action, UploadChannel.video.getCode(), loginUser);
        String token = JwtUtil.createToken(ossPayload, timestamp, secretKey);
        String nonce = UUID.randomUUID().toString();
        String queryString = String.format("token=%s&t=%s&nonce=%s", token, timestamp, nonce);
        String requestString = String.format("%s%s?%s", "GET", url, queryString);
        String sign = SignatureUtil.sign(requestString, secretKey);
        return String.format("%s?token=%s&t=%s&nonce=%s&sign=%s", url, token, timestamp, nonce, sign);
    }

    @Override
    public ObjectInfo getObjectInfo(String objectId) {
        FileMeta fileMeta = fileMetaMapper.findByObjectId(objectId);
        if (fileMeta == null) {
            return null;
        }

        String objectName = fileMeta.getObjectName();
        int fileType = fileMeta.getFileType();
        String filename = fileMeta.getFilename();
        long size = fileMeta.getSize();
        ObjectInfo objectInfo = new ObjectInfo(objectId, objectName, fileType, filename, size);
        if (fileType == 1001) {
            ObjectMeta objectMeta = objectRepository.getObjectMetaById(objectId);
            String absolutePath = objectMeta.getAbsolutePath();
            try {
                ImageOps.Size resolution = ImageOps.info(new File(absolutePath));
                objectInfo.setWidth(resolution.getWidth());
                objectInfo.setHeight(resolution.getHeight());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return objectInfo;
    }

    @Override
    public ObjectUrl getObjectUrl(String objectId) {
        FileMeta fileMeta = fileMetaMapper.findByObjectId(objectId);
        if (fileMeta == null) {
            return null;
        }

        return null;
    }
}
