package cn.timer.api.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;

import cn.hutool.core.util.StrUtil;

/**
 * OSS接口操作示例 1.创建空间 2.上传文件 3.下载文件
 * 
 * @author dsc
 *
 */
public class OSSUtil {

	/**
	 * 1.创建储存空间 sout控制台輸出 储存空间名
	 * @param bucketName OSS空间名
	 * @return 成功信息
	 */
	public static Result<Void> createZone(String bucketName) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
		// 创建存储空间。
		ossClient.createBucket(bucketName);
		// 关闭OSSClient。
		ossClient.shutdown();
		// 控制台输出空间名
		System.err.println("bucketName:" + bucketName);
		// 返回成功
		return ResultUtil.success("创建OSS空间成功");
	}

	/**
	 * 2.上传文件到8time-v2
	 * @param path 上传路径(用'/'分包)
	 * @param ins 输入流
	 * @return
	 */
	public static String uploadFile(String path, InputStream ins) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		// 上传储存空间设置为8time-v2
		String bucketName = "8time-v2";
		// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
		// String objectName = "8time-v2/test/123.jpg";
		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// 创建PutObjectRequest对象。
		// 项目名+用户公司id+模块名+文件夹名+文件名
		PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
				path, ins);
		//[file1,file2,file3],["mk1/img","mk1"]
		// 如果需要上传时设置存储类型与访问权限,请参考以下示例代码。
		// ObjectMetadata metadata = new ObjectMetadata();
		// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS,
		// StorageClass.Standard.toString());
		// metadata.setObjectAcl(CannedAccessControlList.Private);
		// putObjectRequest.setMetadata(metadata);

		// 上传文件。
		ossClient.putObject(putObjectRequest);

		// 设置URL过期时间为100年。                                                                                           1s     1h   1d   1y   100y
		Date expiration = new Date(new Date().getTime() + 1000 * 3600 * 24 * 365 * 100);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName,path, expiration);
		System.err.println(url);
		
		// 关闭OSSClient。
		ossClient.shutdown();
		// 返回上传成功的文件名
		return url.toString();
	}
	
	/**
	 * 3.上传文件到8time-v2-private
	 * @param path 上传路径(用'/'分包)
	 * @param ins 输入流
	 * @return 文件路径
	 */
	public static String uploadPrivateFile(String path, InputStream ins) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		// 上传储存空间设置为8time-v2
		String bucketName = "8time-v2-private";
		// <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
		// String objectName = "8time-v2/test/123.jpg";
		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// 创建PutObjectRequest对象。
		// 项目名+用户公司id+模块名+文件夹名+文件名
		PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
				path, ins);
		//[file1,file2,file3],["mk1/img","mk1"]
		// 如果需要上传时设置存储类型与访问权限,请参考以下示例代码。
		// ObjectMetadata metadata = new ObjectMetadata();
		// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS,
		// StorageClass.Standard.toString());
		// metadata.setObjectAcl(CannedAccessControlList.Private);
		// putObjectRequest.setMetadata(metadata);

		// 上传文件。
		ossClient.putObject(putObjectRequest);

		// 设置URL过期时间为10分钟
		Date expiration = new Date(new Date().getTime() + 1000 * 600);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName,path, expiration);
		System.err.println(url);
		
		// 关闭OSSClient。
		ossClient.shutdown();
		// 返回上传成功的文件名
		return path;
	}

	/**
	 * 4.从OSS下载文件
	 * 
	 * @param objectName 完整路径的文件名
	 * @param path       本地储存文件路径
	 * @param orgCode    公司id
	 * @param dir        包名
	 * @param fileName   文件名
	 * @param moudle     模块名
	 * @return 完整文件名
	 */
	public static Result<String> downloadFile(String orgCode, String moudle, String dir, String fileName, String path) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		// 下载储存空间设置为8time-v2
		String bucketName = "8time-v2";
		// <yourObjectName>从OSS下载文件时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
		// String objectName = "8time-v2/test/123.jpg";
		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
		ossClient.getObject(
				new GetObjectRequest(bucketName, "8timer2.0/" + orgCode + "/" + moudle + "/" + dir + "/" + fileName),
				new File(path + fileName));

		// 关闭OSSClient。
		ossClient.shutdown();
		// 完整路径的文件名
		System.err.println("objectName:" + "8timer2.0/" + orgCode + "/" + moudle + "/" + dir + "/" + fileName);
		System.err.println("path:" + path + fileName);
		// 返回成功的本地路径
		return ResultUtil.success(path + fileName);
	}

	
	public static Result<BufferedReader> downloadFile(String objectName) throws IOException {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		// 下载储存空间设置为8time-v2
		String bucketName = "8time-v2";

		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
		OSSObject ossObject = ossClient.getObject(bucketName, objectName);

		// 读取文件内容。
		System.out.println("Object content:");
		BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));
		while (true) {
			String line = reader.readLine();
			if (line == null)
				break;

			System.out.println("\n" + line);
		}
		// 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。
		reader.close();

		// 关闭OSSClient。
		ossClient.shutdown();
		return ResultUtil.data(reader, "下载成功");
	}

	/**
	 * 文件输入流批量上传
	 * 
	 * @param userBean 获取参数
	 * @param files    批量文件
	 * @return 返回上传成功或失败的信息
	 */
	public static String uploadFile(MultipartHttpServletRequest request,List<MultipartFile> files) {
		
		OSS ossClient = new OSSClientBuilder().build("http://oss-cn-shenzhen.aliyuncs.com", "LTAI4FuaShJWQ1dggsFWG5CC",
				"EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR");

		String newFileName = null;
		URL url = null;
		try {
			// 上传文件
			CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
					request.getSession().getServletContext());
			// 判断 request 是否有文件上传,即多部分请求
			if (multipartResolver.isMultipart(request)) {
				// 转换成多部分request
				MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
				// 取得request中的所有文件名
				Iterator<String> iter = multiRequest.getFileNames();
				// 此处上传单个文件,如需多个文件改为while循环
				while (iter.hasNext()) {
					
					// 取得上传文件
					files = multiRequest.getFiles(iter.next());
					if (files != null) {
						// 取得当前上传文件的文件名称
						String myFileName = null;
						
						for (MultipartFile file : files) {
							myFileName = file.getOriginalFilename();

							// 如果名称不为“”,说明该文件存在,否则说明该文件不存在
							if (StrUtil.isNotEmpty(myFileName.trim())) {
								newFileName = System.currentTimeMillis()
										+ myFileName.substring(myFileName.lastIndexOf("."));
								// 上传客户端文件到oss,如直接上传服务器文件到oss,可使用new FileInputStream( new File("服务器文件路径"))
								ossClient.putObject("8time-v2", newFileName, file.getInputStream());
								// 设置URL过期时间为100年。 1s 1h 1d 1y 100y
								Date expiration = new Date(new Date().getTime() + 1000 * 3600 * 24 * 365 * 100);
								// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
								url = ossClient.generatePresignedUrl("8time-v2", newFileName, expiration);
								System.err.println(url);
							}
							
						}
						
					}
				}
			}
		} catch (IOException e) {
			e.getStackTrace();
		} finally {
			// 关闭ossClient
			if (null != ossClient)
				ossClient.shutdown();
		}
		return url.toString();
		
		/*
		 * if (file == null || file.getSize() <= 0) { return
		 * ResultUtil.error("上传的文件为空,请重新选择!"); } else { try {
		 * OSSUtil.uploadFile(userBean.getOrgCode(), className,
		 * file.getOriginalFilename(), file.getInputStream()); } catch (IOException e) {
		 * e.printStackTrace(); } return ResultUtil.success("上传成功"); }
		 */
	}

	/**
	 * 获取8time-v2文件的url
	 * @return url地址
	 */
	public static String getUrl(String path) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		String bucketName = "8time-v2";

		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// 设置URL过期时间为10年。 1s 1h 1d 1y 10y
		Date expiration = new Date(new Date().getTime() + 1000 * 3600 * 24 * 365 * 10);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName,path, expiration);
		System.err.println(url);
		// 关闭OSSClient。
		ossClient.shutdown();
		return url.toString();
	}

	/**
	 * 获取8time-v2-private文件的url
	 * @return url地址
	 */
	public static String getUrlP(String path) {
		// Endpoint以杭州为例,其它Region请按实际情况填写。
		String endpoint = "http://oss-cn-shenzhen.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
		// https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4FuaShJWQ1dggsFWG5CC";
		String accessKeySecret = "EJ6qToT4T4u0B5Rb6qrta9WkyGHvGR";
		String bucketName = "8time-v2-private";

		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

		// 设置URL过期时间为10分钟。 
		Date expiration = new Date(new Date().getTime() + 1000 * 600);
		// 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
		URL url = ossClient.generatePresignedUrl(bucketName,path, expiration);
		System.err.println(url);
		// 关闭OSSClient。
		ossClient.shutdown();
		return url.toString();
	}
	
	
	
	
	
	
	
	
	/*
	 * (跨域资源) // Endpoint以杭州为例,其它Region请按实际情况填写。 String endpoint =
	 * "http://oss-cn-hangzhou.aliyuncs.com"; //
	 * 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录
	 * https://ram.console.aliyun.com 创建RAM账号 String accessKeyId =
	 * "<yourAccessKeyId>"; String accessKeySecret = "<yourAccessKeySecret>"; String
	 * bucketName = "<yourBucketName>";
	 * 
	 * // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint,
	 * accessKeyId, accessKeySecret);
	 * 
	 * SetBucketCORSRequest request = new SetBucketCORSRequest(bucketName);
	 * 
	 * // 跨域资源共享规则的容器,每个存储空间最多允许10条规则。 ArrayList<CORSRule> putCorsRules = new
	 * ArrayList<CORSRule>();
	 * 
	 * CORSRule corRule = new CORSRule();
	 * 
	 * ArrayList<String> allowedOrigin = new ArrayList<String>(); // 指定允许跨域请求的来源。
	 * allowedOrigin.add( "http://www.b.com");
	 * 
	 * ArrayList<String> allowedMethod = new ArrayList<String>(); //
	 * 指定允许的跨域请求方法(GET/PUT/DELETE/POST/HEAD)。 allowedMethod.add("GET");
	 * 
	 * ArrayList<String> allowedHeader = new ArrayList<String>(); //
	 * 是否允许预取指令(OPTIONS)中Access-Control-Request-Headers头中指定的Header。
	 * allowedHeader.add("x-oss-test");
	 * 
	 * ArrayList<String> exposedHeader = new ArrayList<String>(); //
	 * 指定允许用户从应用程序中访问的响应头。 exposedHeader.add("x-oss-test1"); //
	 * AllowedOrigins和AllowedMethods最多支持一个星号(*)通配符。星号(*)表示允许所有的域来源或者操作。
	 * corRule.setAllowedMethods(allowedMethod);
	 * corRule.setAllowedOrigins(allowedOrigin); //
	 * AllowedHeaders和ExposeHeaders不支持通配符。 corRule.setAllowedHeaders(allowedHeader);
	 * corRule.setExposeHeaders(exposedHeader); //
	 * 指定浏览器对特定资源的预取(OPTIONS)请求返回结果的缓存时间,单位为秒。 corRule.setMaxAgeSeconds(10);
	 * 
	 * // 最多允许10条规则。 putCorsRules.add(corRule); // 已存在的规则将被覆盖。
	 * request.setCorsRules(putCorsRules); ossClient.setBucketCORS(request);
	 * 
	 * // 关闭OSSClient。 ossClient.shutdown();
	 */

}