package com.ytpm.oss.minio;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import com.ytpm.handle.CustomerException;
import com.ytpm.oss.OssAttach;
import com.ytpm.oss.OssProperties;
import com.ytpm.oss.StorageTemplate;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidBucketNameException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.XmlParserException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

public class MinioStorageTemplate implements StorageTemplate {
    private String bucket;

    private MinioClient minioClient;

    @Override
    public void init(OssProperties ossProperties) {
        try {

            this.minioClient = new MinioClient(ossProperties.getEndpoint(), ossProperties.getAccessKey(), ossProperties.getSecretKey());
            this.bucket = ossProperties.getBucket();
            boolean isExists = minioClient.bucketExists(bucket);
            if (!isExists) {
                minioClient.makeBucket(bucket);
                minioClient.setBucketPolicy(bucket,"public");
            }
        } catch (Exception e) {
            throw new CustomerException(e.getMessage());
        }
    }

    @Override
    public String upload(File file) {
        try {
            String filename = getFileName(file);
            PutObjectOptions options = new PutObjectOptions(FileUtil.size(file), PutObjectOptions.MIN_MULTIPART_SIZE);
            minioClient.putObject(bucket, filename, FileUtil.getInputStream(file), options);
            return filename;
        } catch (Exception e) {
            throw new CustomerException(e.getMessage());
        }
    }


    @Override
    public boolean deleteFile(String filename) {
        try {
            minioClient.removeObject(bucket, filename);
        } catch (Exception e) {
            throw new CustomerException(e.getMessage());
        }
        return true;
    }

    @Override
    public OssAttach restore(String filename) {
        String newFileName = getFileName(filename);
        try {
            minioClient.copyObject(bucket, newFileName, null, null, bucket, filename, null, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new OssAttach(newFileName, getUrl(newFileName));
    }

    @Override
    public String getUrl(String filename) {
        String url;
        try {
            url = this.minioClient.getObjectUrl(bucket, filename);
        } catch (Exception e) {
            throw new CustomerException(e.getMessage());
        }
        return url;
    }

    @Override
    public InputStream getStream(String filename) throws IOException, InvalidKeyException, InvalidResponseException,
            InsufficientDataException, NoSuchAlgorithmException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException {
        return minioClient.getObject(bucket, filename);
    }

    private String getFileName(File file) {
        String ym = DateUtil.format(new Date(), "YYYYMM");
        String filename = ym + "/" + ym + IdUtil.fastSimpleUUID() + "." + FileNameUtil.getSuffix(file);

        return filename;
    }

    private String getFileName(String fileName) {
        String ym = DateUtil.format(new Date(), "YYYYMM");
        String filename = ym + "/" + ym + IdUtil.fastSimpleUUID() + "." + FileNameUtil.getSuffix(fileName);

        return filename;
    }
}
