package com.yd.rmi.ali.ossinterf.service.impl;

import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.rmi.ali.ossinterf.service.AliOssInterfService;
import com.yd.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.net.URL;
import java.util.Date;
import java.util.List;

@Service("aliOssInterfService")
public class AliOssInterfServiceImpl implements AliOssInterfService {
    private String endpoint = null;//SystemConstants.ALI_OSS_ENDPOINT;
    private String accessKeyId = null;//SystemConstants.ALI_OSS_ACCESS_KEY_ID;
    private String accessKeySecret = null;//SystemConstants.ALI_OSS_ACCESS_KEY_SECRET;
    
    @Autowired
    private SystemConfigService systemConfigService;

    public void initAttribute(){
    	if(CommonUtil.isNullOrBlank(this.endpoint)){
    		this.endpoint = systemConfigService.getSingleConfigValue("ALI_OSS_ENDPOINT");
    	}
    	if(CommonUtil.isNullOrBlank(this.accessKeyId)){
    		this.accessKeyId = systemConfigService.getSingleConfigValue("ALI_OSS_ACCESS_KEY_ID");
    	}
    	if(CommonUtil.isNullOrBlank(this.accessKeySecret)){
    		this.accessKeySecret = systemConfigService.getSingleConfigValue("ALI_OSS_ACCESS_KEY_SECRET");
    	}
    }

    /**
     * 初始化相关链接参数
     * @param endpoint
     * @param accessKeyId
     * @param accessKeySecret
     */
    public void initAttribute(String endpoint,String accessKeyId,String accessKeySecret){
    	if(!CommonUtil.isNullOrBlank(endpoint)){
    		this.endpoint = endpoint;
    	}
    	if(!CommonUtil.isNullOrBlank(accessKeyId)){
    		this.accessKeyId = accessKeyId;
    	}
    	if(!CommonUtil.isNullOrBlank(accessKeySecret)){
    		this.accessKeySecret = accessKeySecret;
    	}
    }

    /**
     * 判断存储空间是否存在
     * @param bucketName 存储空间名
     * @return
     */
	public boolean doesBucketExist(String bucketName){
		boolean result = false;
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		try{
			result = ossClient.doesBucketExist(bucketName);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return result;
	}
	/**
	 * 获取存储空间访问权限
	 * @param bucketName 存储空间名
	 * @return
	 */
	public AccessControlList getBucketAcl(String bucketName){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		AccessControlList accessControlList = null;
		try{
			accessControlList = ossClient.getBucketAcl(bucketName);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return accessControlList;
	}
	
	/**
	 * 创建存储空间
	 * @param bucketName 存储空间名
	 * @param cannedACL 访问权限
	 */
	public void createBucket(String bucketName,CannedAccessControlList cannedACL){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		try{
			CreateBucketRequest createBucketRequest= new CreateBucketRequest(bucketName);
			createBucketRequest.setCannedACL(cannedACL);
			ossClient.createBucket(createBucketRequest);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
	}
	
	/**
	 * 设置存储空间访问权限
	 * @param bucketName 存储空间名
	 * @param cannedACL 访问权限
	 */
	public void setBucketAcl(String bucketName,CannedAccessControlList cannedACL){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		try{
			ossClient.setBucketAcl(bucketName, cannedACL);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
	}
	
	/**
	 * 列出当前访问域名下的所有存储空间
	 * @return
	 */
	public BucketList listBuckets(){
		BucketList bucketList = null;
		ListBucketsRequest listBucketsRequest = new ListBucketsRequest();
        listBucketsRequest.setMaxKeys(500);
        
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		try{
			bucketList = ossClient.listBuckets(listBucketsRequest);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return bucketList;
	}

	/**
	 * 判断对象是否存在
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @return
	 */
	public boolean doesObjectExist(String bucketName,String key){
		boolean result = false;
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		
		try{
			result = ossClient.doesObjectExist(bucketName, key);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return result;
	}
	
	/**
	 * 获取对象的访问权限
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @return
	 */
	public ObjectAcl getObjectAcl(String bucketName,String key){
		ObjectAcl objectAcl = null;
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		
		try{
			objectAcl = ossClient.getObjectAcl(bucketName, key);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return objectAcl;
	}
	
	/**
	 * 上传文件
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @param file 文件
	 */
	public void putObject(String bucketName,String key,File file){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		
		try{
			ossClient.putObject(new PutObjectRequest(bucketName, key, file));
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
	}
	
	/**
	 * 设置对象访问权限
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @param cannedACL 访问权限
	 */
	public void setObjectAcl(String bucketName,String key, CannedAccessControlList cannedACL){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		
		try{
			ossClient.setObjectAcl(bucketName, key, cannedACL);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
	}
	
	/**
	 * 下载对象
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @return
	 */
	public OSSObject getObject(String bucketName,String key){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		OSSObject object = null;
		try{
			object = ossClient.getObject(bucketName, key);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return object;
	}
	
	/**
	 * 列出当前访问域名下的所有对象
	 * @param bucketName 存储空间名
	 * @param prefix 
	 * @return
	 */
	public ObjectListing listObjects(String bucketName, String prefix){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		ObjectListing objectListing = null;
		try{
			objectListing = ossClient.listObjects(bucketName, prefix);
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return objectListing;
	}
	
	/**
	 * 获取对象外网访问URL
	 * @param bucketName 存储空间名
	 * @param key 对象名
	 * @return
	 */
	@Override
	public String generateUrl(String bucketName, String key){
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		String url = null;
		try{
			ObjectAcl objectAcl = ossClient.getObjectAcl(bucketName, key);
			boolean isPrivate = false;
			if((objectAcl.getPermission().toString()).equals(CannedAccessControlList.Private.toString())){
				isPrivate = true;
			}if((objectAcl.getPermission().toString()).equals(CannedAccessControlList.Default.toString())){
				AccessControlList accessControlList = ossClient.getBucketAcl(bucketName);
				if( (accessControlList.getCannedACL().toString()).equals(CannedAccessControlList.Private.toString()) ){
					isPrivate = true;
				}
			}
			if(isPrivate){
				Date expiration = CommonUtil.dateOperation(new Date(), "ADD", "H", 2);
				GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET);
				request.setExpiration(expiration);
				URL signedUrl = ossClient.generatePresignedUrl(request);
				url = signedUrl.toString();
			}else{
				url = endpoint.replace("https://", "https://"+bucketName+".")+"/"+key;
			}
			
		}catch (Exception e) {
			e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
		}finally {
	        ossClient.shutdown();
	    }
		return url;
	}

	/**
	 * 删除对象
	 * @param bucketName 存储空间名
	 * @param keys 对象名列表
	 */
	public void deleteObjects(String bucketName,List<String> keys){
        OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try{
            client.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
        }catch (Exception e) {
        	e.printStackTrace();
//			CommonUtil.parseExceptionStack(e);
        }finally {
            client.shutdown();
        }
	}

}
