package com.xunhong.erp.turbo.file;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.auth.sts.AssumeRoleRequest;
import com.aliyuncs.auth.sts.AssumeRoleResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.xunhong.erp.turbo.base.exception.BizException;
import com.xunhong.erp.turbo.file.infrastructure.exception.FileErrorCode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.io.InputStream;

/**
 * oss 服务
 *
 * @author shenyifei
 */
@Slf4j
@Setter
public class OssServiceImpl implements FileService {
	private String roleArn;

	private String region;

	private String bucket;

	private String stsEndPoint;

	private String ossEndPoint;

	private String accessKey;

	private String accessSecret;

	private String policy;


	@Override
	public AssumeRoleResponse.Credentials getOssToken() {
		String endPoint = stsEndPoint;
		try {
			DefaultProfile.addEndpoint("", region, "Sts", endPoint);
			DefaultProfile profile = DefaultProfile.getProfile(region, accessKey, accessSecret);
			DefaultAcsClient client = new DefaultAcsClient(profile);
			AssumeRoleRequest assumeRoleRequest = this.getAssumeRoleRequest();
			AssumeRoleResponse acsResponse = client.getAcsResponse(assumeRoleRequest);
			if (null == acsResponse) {
				throw new BizException(FileErrorCode.OSS_TOKEN_FAIL);
			}

			return acsResponse.getCredentials();
		} catch (ClientException e) {
			throw new BizException(FileErrorCode.OSS_TOKEN_FAIL);
		}
	}

	private AssumeRoleRequest getAssumeRoleRequest() {
		AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest();
		assumeRoleRequest.setMethod(MethodType.POST);
		assumeRoleRequest.setRoleArn(roleArn);
		assumeRoleRequest.setRoleSessionName(bucket);
		assumeRoleRequest.setPolicy(policy);

		assumeRoleRequest.setDurationSeconds(3600L);
		return assumeRoleRequest;
	}

	@Override
	public boolean upload(String path, InputStream fileStream) {
		// Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
		String endpoint = ossEndPoint;
		// 从环境变量中获取RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
		String accessKeyId = accessKey;
		String accessKeySecret = accessSecret;
		// 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
		CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

		// 填写Bucket名称，例如examplebucket。
		String bucketName = bucket;
		// 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
		String objectName = path;

		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
		boolean uploadRes = false;
		try {

			// 创建PutObjectRequest对象。
			PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, fileStream);

			// 上传字符串。
			PutObjectResult result = ossClient.putObject(putObjectRequest);
			if (StringUtils.isNotBlank(result.getRequestId())) {
				uploadRes = true;
			}
		} catch (Exception e) {
			log.error("OssUtil upload error,path=" + path, e);
		} finally {
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}
		return uploadRes;
	}

	@Override
	public boolean upload(String path, File file) {
		// Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
		String endpoint = ossEndPoint;
		// 从环境变量中获取RAM用户的访问密钥（AccessKey ID和AccessKey Secret）。
		String accessKeyId = accessKey;
		String accessKeySecret = accessSecret;
		// 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
		CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

		// 填写Bucket名称，例如examplebucket。
		String bucketName = bucket;
		// 填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
		String objectName = path;

		// 创建OSSClient实例。
		OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
		boolean uploadRes = false;
		try {

			// 创建PutObjectRequest对象。
			PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file);

			// 上传字符串。
			PutObjectResult result = ossClient.putObject(putObjectRequest);
			if (StringUtils.isNotBlank(result.getRequestId())) {
				uploadRes = true;
			}
		} catch (Exception e) {
			log.error("OssUtil upload error,path=" + path, e);
		} finally {
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}
		return uploadRes;
	}
}
