package com.org.hktshop.service.aliyun;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.org.hktshop.properties.AliyunOSSProperties;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class AliyunOssService {
    @Autowired
    private AliyunOSSProperties aliyunOSSProperties;
    private static Logger logger = LoggerFactory.getLogger(AliyunOssService.class);
    private final static String PIC_SUFFIX = ".jpeg|.jpg|.png|.gif";
    private final static String VIDEO_SUFFIX = ".wmv|.asf|.asx|.rm|.rmvb|.mp4|.3gp|.mov|.m4v|.avi|.dat|.mkv|.flv|.vob";
    private final static String OFFICE_SUFFIX = ".doc|.docx|.xls|.xlsx|.ppt|.pptx|.pdf";


    /**
     * 默认文件夹
     */
    private static String folder = "default";

    /**
     * @param ossClient  oss客户端
     * @param url        URL
     * @param bucketName bucket名称
     * @param objectName 上传文件目录和（包括文件名）例如“test/index.html”
     * @return void        返回类型
     * @Title: uploadByNetworkStream
     * @Description: 通过网络流上传文件
     */
    public void uploadByNetworkStream(OSSClient ossClient, URL url, String bucketName, String objectName) {
        try {
            InputStream inputStream = url.openStream();
            ossClient.putObject(bucketName, objectName, inputStream);
            ossClient.shutdown();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * @param uploadFile 上传的文件
     * @return void        返回类型
     * @Title: uploadByFile
     * @Description: 通过file上传文件
     */
    public String uploadByFile(OSSClient ossClient, MultipartFile uploadFile, String folder) {

        String url = null;
        try {
            String filename = aliyunOSSProperties.getFileHost() + "/" + folder + "/" + uploadFile.getOriginalFilename();//.getOriginalFilename().substring(uploadFile.getOriginalFilename().lastIndexOf("."));
            uploadByInputStream(ossClient, new ByteArrayInputStream(uploadFile.getBytes()), aliyunOSSProperties.getBucketName(), filename);
            //36000 * 1000 * 24 * 365 * 10
            Date expiration = new Date(System.currentTimeMillis());
            String path = ossClient.generatePresignedUrl(aliyunOSSProperties.getBucketName(), filename, expiration).toString();
            url = path.substring(0, path.indexOf("?"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return url;
    }

    public String uploadForStr(OSSClient ossClient, String Conten, String fileName) throws UnsupportedEncodingException {

        String filename = aliyunOSSProperties.getFileHost() + "/" + fileName;
        uploadByInputStream(ossClient, new ByteArrayInputStream(Conten.getBytes("unicode")), aliyunOSSProperties.getBucketName(), filename);
        Date expiration = new Date(System.currentTimeMillis());
        String path = ossClient.generatePresignedUrl(aliyunOSSProperties.getBucketName(), filename, expiration).toString();
        return path.substring(0, path.indexOf("?"));
    }

    public String loadFileFromUrl(OSSClient ossClient, String url, String path) throws IOException {

        String[] urlArr = url.split("/");
        String name = urlArr[urlArr.length - 1];

        String filename = aliyunOSSProperties.getFileHost() + "/" + path + "/" + name;
        InputStream inputStream = new URL(url).openStream();

        uploadByInputStream(ossClient, inputStream, aliyunOSSProperties.getBucketName(), filename);
        Date expiration = new Date(System.currentTimeMillis());
        String retValue = ossClient.generatePresignedUrl(aliyunOSSProperties.getBucketName(), filename, expiration).toString();
        return retValue.substring(0, retValue.indexOf("?"));
    }

    /**
     * @param ossClient   oss客户端
     * @param inputStream 输入流
     * @param bucketName  bucket名称
     * @param objectName  上传文件目录和（包括文件名） 例如“test/a.jpg”
     * @return void        返回类型
     * @Title: uploadByInputStream
     * @Description: 通过输入流上传文件
     */
    public void uploadByInputStream(OSSClient ossClient, InputStream inputStream, String bucketName,
                                    String objectName) {
        try {
            ossClient.putObject(bucketName, objectName, inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * @param key 文件路径/名称，例如“test/a.txt”
     * @return void            返回类型
     * @Title: deleteFile
     * @Description: 根据key删除oss服务器上的文件
     */
    public boolean deleteFile(OSSClient ossClient, String key) {
        try {
            boolean exist = ossClient.doesObjectExist(aliyunOSSProperties.getBucketName(), key);
            if (!exist) {
                logger.error("文件不存在,filePath={}", key);
                return false;
            }
            logger.info("删除文件,filePath={}", key);
            ossClient.deleteObject(aliyunOSSProperties.getBucketName(), key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return true;
    }

    /**
     * @param key 文件路径和名称
     * @return InputStream    文件输入流
     * @Title: getInputStreamByOSS
     * @Description:根据key获取服务器上的文件的输入流
     */
    public String getInputStreamByOSS(OSSClient ossClient, String key) {
        InputStream content = null;
        BufferedReader reader = null;
        try {
            if (!key.contains(aliyunOSSProperties.getFileHost())) return "";
            OSSObject ossObj = ossClient.getObject(aliyunOSSProperties.getBucketName(), key.substring(key.indexOf(aliyunOSSProperties.getFileHost())));
            content = ossObj.getObjectContent();

            reader = new BufferedReader(new InputStreamReader(content, "unicode"));
            StringBuffer sb = new StringBuffer();
            while (true) {
                String line = reader.readLine();
                if (line == null) break;
                sb.append(line);
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(key);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception ex) {
                }
            }
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    /**
     * @param key 文件路径和名称
     */
    public String getTxtMsg(OSSClient oSSClient, String key) {
        String txt = getInputStreamByOSS(oSSClient, key);
        return txt;
    }

    /**
     * @param ossClient  oss客户端
     * @param bucketName bucket名称
     * @return List<String>  文件路径和大小集合
     * @Title: queryAllObject
     * @Description: 查询某个bucket里面的所有文件
     */
    public List<String> queryAllObject(OSSClient ossClient, String bucketName) {
        List<String> results = new ArrayList<String>();
        try {
            // ossClient.listObjects返回ObjectListing实例，包含此次listObject请求的返回结果。
            ObjectListing objectListing = ossClient.listObjects(bucketName);
            // objectListing.getObjectSummaries获取所有文件的描述信息。
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                results.add(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return results;
    }

    public String getFolderName(String fileName) {
        String suffix = fileName.substring(fileName.indexOf("."), fileName.length());
        Matcher picMatcher = Pattern.compile(PIC_SUFFIX).matcher(suffix);
        if (picMatcher.matches()) {
            folder = "pic";
        }
        Matcher videoMatcher = Pattern.compile(VIDEO_SUFFIX).matcher(suffix);
        if (videoMatcher.matches()) {
            folder = "video";
        }
        Matcher officeMatcher = Pattern.compile(OFFICE_SUFFIX).matcher(suffix);
        if (officeMatcher.matches()) {
            folder = "office";
        }
        return folder;
    }
}

