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

import com.aliyun.oss.model.*;
import com.yd.api.result.CommonResult;
import com.yd.rmi.cache.SystemConfigService;
import com.yd.rmi.ali.oss.service.OssService;
import com.yd.rmi.ali.oss.vo.OssOperateTypeEnum;
import com.yd.rmi.ali.oss.vo.OssRequestVO;
import com.yd.rmi.ali.oss.vo.OssResponseVO;
import com.yd.rmi.ali.ossinterf.service.AliOssInterfService;
import com.yd.util.CommonUtil;
import com.yd.util.config.ZHBErrorConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

@Service("ossService")
public class OssServiceImpl implements OssService {
	@Autowired
	private SystemConfigService systemConfigService;
	@Autowired
	private AliOssInterfService aliOssInterfService;

	public boolean doesBucketExist(String bucketName){
		String endpoint = systemConfigService.getSingleConfigValue("ALI_OSS_ENDPOINT");
		String accessKeyId = systemConfigService.getSingleConfigValue("ALI_OSS_ACCESS_KEY_ID");
		String accessKeySecret = systemConfigService.getSingleConfigValue("ALI_OSS_ACCESS_KEY_SECRET");
		aliOssInterfService.initAttribute(endpoint, accessKeyId, accessKeySecret);
		
		return aliOssInterfService.doesBucketExist(bucketName);
	}

	/**
	 * 上传文件到OSS
	 * @param bucketName
	 * @param key
	 * @param is
	 * @return
	 */
	@Override
	public String putFileToOss(String bucketName, String key, InputStream is) throws Exception{
		String url = null;
		if(CommonUtil.isNullOrBlank(key) || is == null){
			return null;
		}

		if(CommonUtil.isNullOrBlank(bucketName)){
			bucketName = systemConfigService.getSingleConfigValue("ALI_OSS_BUCKET_NAME");
		}
		OssRequestVO ossRequestVO = new OssRequestVO();
		File file = null;
		OutputStream os = null;
		try{
			file = File.createTempFile("tmp", null);
//			System.out.println("文件是否存在："+file.exists()+"---------------临时文件路径："+file.getAbsolutePath());
			os = new FileOutputStream(file);
			int len = 0;
			byte[] bytes = new byte[1024];
			while((len = is.read(bytes) ) > 0){
				os.write(bytes, 0, len);
				os.flush();
			}
			ossRequestVO.setOperateType(OssOperateTypeEnum.PUT_OBJECT.getCode());
			ossRequestVO.setBucketName(bucketName);
			ossRequestVO.setKey(key);
			ossRequestVO.setFile(file);
			OssResponseVO ossResponseVO = ossOperate(ossRequestVO);

			ossRequestVO.setOperateType(OssOperateTypeEnum.GENERATE_URL.getCode());
			ossResponseVO = ossOperate(ossRequestVO);
			url = ossResponseVO.getUrl();
		}catch(Exception e){
			throw e;
		}finally{
			if(os != null){try{os.close();}catch(Exception e){e.printStackTrace();}}
			if(is != null){try{is.close();}catch(Exception e){e.printStackTrace();}}
			if(file != null){file.delete();}
//			System.out.println("文件是否存在："+file.exists());
		}
		return url;
	}
	@Override
	public OssResponseVO ossOperate(OssRequestVO ossRequestVO) {
		OssResponseVO ossResponseVO = new OssResponseVO();
		boolean success = true;
		String message = ZHBErrorConfig.getErrorInfo("800000");
		
		if(ossRequestVO == null || CommonUtil.isNullOrBlank(ossRequestVO.getOperateType())){
			String[] params = {"operateType"};
			ossResponseVO.setCommonResult(new CommonResult(false,ZHBErrorConfig.getErrorInfo("610001", params)));
			return ossResponseVO;
		}
		String operateType = ossRequestVO.getOperateType();
		String bucketName = ossRequestVO.getBucketName();
		CannedAccessControlList cannedAccessControlList = ossRequestVO.getCannedAccessControlList();
		String key = ossRequestVO.getKey();
		File file = ossRequestVO.getFile();
		
		String checkMessage = "";
		if(OssOperateTypeEnum.DOES_BUCKET_EXIST.getCode().equals(operateType)
				|| OssOperateTypeEnum.GET_BUCKET_ACL.getCode().equals(operateType)
				|| OssOperateTypeEnum.CREATE_BUCKET.getCode().equals(operateType)
				|| OssOperateTypeEnum.SET_BUCKET_ACL.getCode().equals(operateType)
				|| OssOperateTypeEnum.DOES_OBJECT_EXIST.getCode().equals(operateType)
				|| OssOperateTypeEnum.GET_OBJECT_ACL.getCode().equals(operateType)
				|| OssOperateTypeEnum.PUT_OBJECT.getCode().equals(operateType)
				|| OssOperateTypeEnum.SET_OBJECT_ACL.getCode().equals(operateType)
				|| OssOperateTypeEnum.GET_OBJECT.getCode().equals(operateType)
				|| OssOperateTypeEnum.LIST_OBJECTS.getCode().equals(operateType)
				|| OssOperateTypeEnum.GENERATE_URL.getCode().equals(operateType)
				|| OssOperateTypeEnum.DELETE_OBJECTS.getCode().equals(operateType)){
			
			if(CommonUtil.isNullOrBlank(bucketName)){
				String[] params = {"bucketName"};
				checkMessage += ZHBErrorConfig.getErrorInfo("610001", params);
			}
			
			if(OssOperateTypeEnum.DOES_OBJECT_EXIST.getCode().equals(operateType)
					|| OssOperateTypeEnum.GET_OBJECT_ACL.getCode().equals(operateType)
					|| OssOperateTypeEnum.PUT_OBJECT.getCode().equals(operateType)
					|| OssOperateTypeEnum.SET_OBJECT_ACL.getCode().equals(operateType)
					|| OssOperateTypeEnum.GET_OBJECT.getCode().equals(operateType)
					|| OssOperateTypeEnum.GENERATE_URL.getCode().equals(operateType)
					|| OssOperateTypeEnum.DELETE_OBJECTS.getCode().equals(operateType)){
				
				if(CommonUtil.isNullOrBlank(key)){
					String[] params = {"key"};
					checkMessage += ZHBErrorConfig.getErrorInfo("610001", params);
				}
			}
			
			if(OssOperateTypeEnum.SET_BUCKET_ACL.getCode().equals(operateType)
					|| OssOperateTypeEnum.SET_OBJECT_ACL.getCode().equals(operateType)){
				if(cannedAccessControlList == null){
					String[] params = {"cannedAccessControlList"};
					checkMessage += ZHBErrorConfig.getErrorInfo("610001", params);
				}
			}
			
			if(OssOperateTypeEnum.PUT_OBJECT.getCode().equals(operateType)){
				if(file == null){
					String[] params = {"file"};
					checkMessage += ZHBErrorConfig.getErrorInfo("610001", params);
				}
			}
		}
		if(!CommonUtil.isNullOrBlank(checkMessage)){
			ossResponseVO.setCommonResult(new CommonResult(false,checkMessage));
			return ossResponseVO;
		}
		
		if(OssOperateTypeEnum.DOES_BUCKET_EXIST.getCode().equals(operateType)){
			boolean isExists = aliOssInterfService.doesBucketExist(bucketName);
			ossResponseVO.setExists(isExists);	
		}else if(OssOperateTypeEnum.GET_BUCKET_ACL.getCode().equals(operateType)){
			AccessControlList accessControlList = aliOssInterfService.getBucketAcl(bucketName);
			ossResponseVO.setAccessControlList(accessControlList);
		}else if(OssOperateTypeEnum.CREATE_BUCKET.getCode().equals(operateType)){
			aliOssInterfService.createBucket(bucketName, cannedAccessControlList);
		}else if(OssOperateTypeEnum.SET_BUCKET_ACL.getCode().equals(operateType)){
			aliOssInterfService.setBucketAcl(bucketName, cannedAccessControlList);
		}else if(OssOperateTypeEnum.LIST_BUCKETS.getCode().equals(operateType)){
			BucketList bucketList = aliOssInterfService.listBuckets();
			ossResponseVO.setBucketList(bucketList);
		}else if(OssOperateTypeEnum.DOES_OBJECT_EXIST.getCode().equals(operateType)){
			boolean isExists = aliOssInterfService.doesObjectExist(bucketName, key);
			ossResponseVO.setExists(isExists);	
		}else if(OssOperateTypeEnum.GET_OBJECT_ACL.getCode().equals(operateType)){
			ObjectAcl objectAcl = aliOssInterfService.getObjectAcl(bucketName, key);
			ossResponseVO.setObjectAcl(objectAcl);
		}else if(OssOperateTypeEnum.PUT_OBJECT.getCode().equals(operateType)){
			aliOssInterfService.putObject(bucketName, key, file);
		}else if(OssOperateTypeEnum.SET_OBJECT_ACL.getCode().equals(operateType)){
			aliOssInterfService.setObjectAcl(bucketName, key, cannedAccessControlList);
		}else if(OssOperateTypeEnum.GET_OBJECT.getCode().equals(operateType)){
			OSSObject ossObject = aliOssInterfService.getObject(bucketName, key);
			ossResponseVO.setOssObject(ossObject);
		}else if(OssOperateTypeEnum.LIST_OBJECTS.getCode().equals(operateType)){
			ObjectListing objectListing = aliOssInterfService.listObjects(bucketName, ossRequestVO.getPrefix());
			ossResponseVO.setObjectListing(objectListing);
		}else if(OssOperateTypeEnum.GENERATE_URL.getCode().equals(operateType)){
			String url = aliOssInterfService.generateUrl(bucketName, key);
			ossResponseVO.setUrl(url);
		}else if(OssOperateTypeEnum.DELETE_OBJECTS.getCode().equals(operateType)){
			List<String> keys = new ArrayList<String>();
			keys.add(key);
			aliOssInterfService.deleteObjects(bucketName, keys);
		}
		ossResponseVO.setCommonResult(new CommonResult(success,message));
		return ossResponseVO;
	}
}
