package cn.com.poc.common.service.impl;

import cn.com.poc.common.service.BosConfigService;
import cn.com.poc.common.utils.Assert;
import cn.com.poc.common.utils.UUIDTool;
import cn.com.yict.framemax.core.config.Config;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import cn.com.yict.framemax.frame.service.FmxParamConfigService;
import com.baidubce.auth.BceCredentials;
import com.baidubce.auth.DefaultBceCredentials;
import com.baidubce.services.bos.BosClient;
import com.baidubce.services.bos.BosClientConfiguration;
import com.baidubce.services.bos.model.ObjectMetadata;
import com.baidubce.services.bos.model.PutObjectRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
import java.util.Optional;


@Service
public class BosConfigServiceImpl implements BosConfigService {

    @Resource
    private FmxParamConfigService fmxParamConfigService;


    @Override
    public String uploadFileByByteArray2Oss(byte[] decodedByte, String uploadFolder, String fileName, String fileType)
            throws IOException {
        String BUCKET_NAME = fmxParamConfigService.getParam("bos.bucketName");
        String END_POINT = fmxParamConfigService.getParam("bos.endPoint");
        String FILE_NAME = fileName + "." + fileType;

        BosClient client = getClient();
        ObjectMetadata meta = new ObjectMetadata();
        // 设置内容被下载时的名称。
        if (StringUtils.isNoneBlank(FILE_NAME)) {
            meta.setContentDisposition("attachment; filename=" + FILE_NAME);
        }
        // 设置内容被下载时的编码格式。
        meta.setContentEncoding("utf-8");
        meta.setContentLength(decodedByte.length);
        // 设置上传目录
        String PUT_OBJECT_REQUEST_KEY = uploadFolder + FILE_NAME;
        //上传文件
        client.putObject(BUCKET_NAME, PUT_OBJECT_REQUEST_KEY, decodedByte);
        client.shutdown();
        // 拼接下载地址
        return "https://" +
                BUCKET_NAME +
                "." +
                END_POINT.replaceAll("http://", "").replaceAll("https://", "") +
                "/" +
                PUT_OBJECT_REQUEST_KEY;
    }

    @Override
    public String uploadFileByByteArray2Oss(byte[] decodedByte, String fileName, String fileType) throws IOException {
        String date = DateUtils.formatDate(new Date(), "yyyyMMdd");
        String UPLOAD_FLODER = fmxParamConfigService.getParam("bos.uploadFolder");
        if (UPLOAD_FLODER.endsWith("/")) {
            UPLOAD_FLODER = UPLOAD_FLODER + date + "/";

        } else {
            UPLOAD_FLODER = UPLOAD_FLODER + "/" + date + "/";
        }
        return this.uploadFileByByteArray2Oss(decodedByte, UPLOAD_FLODER, fileName, fileType);
    }

    @Override
    public String upload(InputStream inputStream, String fileType, String contentType, String fileName)
            throws IOException {
        String BUCKET_NAME = fmxParamConfigService.getParam("bos.bucketName");
        String END_POINT = fmxParamConfigService.getParam("bos.endPoint");
        String FILE_NAME = createFileName(fileType);
        BosClient client = getClient();
        try {
            ObjectMetadata meta = new ObjectMetadata();
            meta.setContentType(contentType);
            // 设置内容被下载时的名称。
            if (StringUtils.isNoneBlank(FILE_NAME)) {
                String downloadName = fileName + "." + fileType;
                String encoded = URLEncoder.encode(downloadName, StandardCharsets.UTF_8.name());
                meta.setContentDisposition("attachment; filename=" + encoded);
            }
            // 设置内容被下载时的编码格式。
            meta.setContentEncoding(StandardCharsets.UTF_8.displayName());
            meta.setContentLength(inputStream.available());

            // 设置上传目录
            String date = DateUtils.formatDate(new Date(), "yyyyMMdd");
            String UPLOAD_FLODER = fmxParamConfigService.getParam("bos.uploadFolder");
            // 如果上传目录不以【/】结尾，加上
            if (UPLOAD_FLODER.endsWith("/")) {
                UPLOAD_FLODER = UPLOAD_FLODER + date + "/";

            } else {
                UPLOAD_FLODER = UPLOAD_FLODER + "/" + date + "/";
            }
            String PUT_OBJECT_REQUEST_KEY = UPLOAD_FLODER + FILE_NAME;

            //上传文件
            PutObjectRequest request = new PutObjectRequest(BUCKET_NAME, PUT_OBJECT_REQUEST_KEY, inputStream);
            request.withStorageClass(BosClient.STORAGE_CLASS_STANDARD);
            request.setObjectMetadata(meta);

            client.putObject(request);
            client.shutdown();
            inputStream.close();

            // 拼接下载地址
            return "https://" +
                    BUCKET_NAME +
                    "." +
                    END_POINT.replaceAll("http://", "").replaceAll("https://", "") +
                    "/" +
                    PUT_OBJECT_REQUEST_KEY;
        } catch (IOException e) {
            throw new RuntimeException(e.getLocalizedMessage());
        } finally {
            client.shutdown();
        }
    }

    @Override
    public String upload(InputStream inputStream, String fileType, String contentType) throws IOException {
        return upload(inputStream, fileType, contentType, createFileName(fileType));
    }


    @Override
    public String uploadImageByBase64(String base64) throws IOException {
        Assert.notBlank(base64);
        byte[] decode = Base64.getDecoder().decode(base64);
        String fileType = "jpeg";
        return this.uploadFileByByteArray2Oss(decode, UUIDTool.getUUID(), fileType);
    }

    @Override
    public String uploadImageByUrl2Bos(String path) throws IOException {
        StringBuffer resultUrl = new StringBuffer();
        String fileType = "jpeg";
        URL url = new URL(path);
        HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();
        httpUrl.setRequestMethod("GET");
        httpUrl.usingProxy();
        httpUrl.connect();
        InputStream inputStream = new BufferedInputStream(httpUrl.getInputStream());
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[4096];
        int n = 0;
        while (-1 != (n = inputStream.read(buffer))) {
            output.write(buffer, 0, n);
        }
        byte[] content = output.toByteArray();
        return this.uploadFileByByteArray2Oss(content, UUIDTool.getUUID(), fileType);
    }

    //返回即将创建的文件名
    private String createFileName(String fileType) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(System.currentTimeMillis()).
                append(".").
                append(Optional.ofNullable(fileType).orElse(""));
        return stringBuilder.toString();
    }

    private BosClient getClient() {
        String ACCESS_KEY_ID = Config.get("baidu.code.keyId");
        String SECRET_ACCESS_KEY = Config.get("baidu.code.keySecret");
        String END_POINT = fmxParamConfigService.getParam("bos.endPoint");
        BceCredentials credentials = new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY);
        BosClientConfiguration config = new BosClientConfiguration();
        config.setCredentials(credentials);
        config.setEndpoint(END_POINT);
        return new BosClient(config);
    }
}

