//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springblade.core.oss;

import io.minio.BucketExistsArgs;
import io.minio.CopyObjectArgs;
import io.minio.CopySource;
import io.minio.GetObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveBucketArgs;
import io.minio.RemoveObjectArgs;
import io.minio.RemoveObjectsArgs;
import io.minio.SetBucketPolicyArgs;
import io.minio.StatObjectArgs;
import io.minio.StatObjectResponse;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import java.io.InputStream;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import lombok.SneakyThrows;
import org.springblade.core.oss.enums.PolicyType;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.oss.model.OssFile;
import org.springblade.core.oss.props.OssProperties;
import org.springblade.core.oss.rule.OssRule;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.web.multipart.MultipartFile;

public class MinioTemplate implements OssTemplate {
	private final MinioClient client;
	private final OssRule ossRule;
	private final OssProperties ossProperties;

	@SneakyThrows
	public void makeBucket(String bucketName) {
		try {
			if (!this.client.bucketExists((BucketExistsArgs)((BucketExistsArgs.Builder)BucketExistsArgs.builder().bucket(this.getBucketName(bucketName))).build())) {
				this.client.makeBucket((MakeBucketArgs)((MakeBucketArgs.Builder)MakeBucketArgs.builder().bucket(this.getBucketName(bucketName))).build());
				this.client.setBucketPolicy((SetBucketPolicyArgs)((SetBucketPolicyArgs.Builder)SetBucketPolicyArgs.builder().bucket(this.getBucketName(bucketName))).config(getPolicyType(this.getBucketName(bucketName), PolicyType.READ)).build());
			}

		} catch (Throwable var3) {
			throw var3;
		}
	}

	public Bucket getBucket() {
		try {
			return this.getBucket(this.getBucketName());
		} catch (Throwable var2) {
			throw var2;
		}
	}

	@SneakyThrows
	public Bucket getBucket(String bucketName) {
		try {
			Optional<Bucket> bucketOptional = this.client.listBuckets().stream().filter((bucket) -> {
				return bucket.name().equals(this.getBucketName(bucketName));
			}).findFirst();
			return bucketOptional.orElse( null);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	@SneakyThrows
	public List<Bucket> listBuckets() {
		try {
			return this.client.listBuckets();
		} catch (Throwable var2) {
			throw var2;
		}
	}

	@SneakyThrows
	public void removeBucket(String bucketName) {
		try {
			this.client.removeBucket((RemoveBucketArgs)((RemoveBucketArgs.Builder)RemoveBucketArgs.builder().bucket(this.getBucketName(bucketName))).build());
		} catch (Throwable var3) {
			throw var3;
		}
	}

	@SneakyThrows
	public boolean bucketExists(String bucketName) {
		try {
			return this.client.bucketExists((BucketExistsArgs)((BucketExistsArgs.Builder)BucketExistsArgs.builder().bucket(this.getBucketName(bucketName))).build());
		} catch (Throwable var3) {
			throw var3;
		}
	}

	public void copyFile(String bucketName, String fileName, String destBucketName) {
		try {
			this.copyFile(bucketName, fileName, destBucketName, fileName);
		} catch (Throwable var5) {
			throw var5;
		}
	}

	@SneakyThrows
	public void copyFile(String bucketName, String fileName, String destBucketName, String destFileName) {
		try {
			this.client.copyObject((CopyObjectArgs)((CopyObjectArgs.Builder)((CopyObjectArgs.Builder)CopyObjectArgs.builder().source((CopySource)((CopySource.Builder)((CopySource.Builder)CopySource.builder().bucket(this.getBucketName(bucketName))).object(fileName)).build()).bucket(this.getBucketName(destBucketName))).object(destFileName)).build());
		} catch (Throwable var6) {
			throw var6;
		}
	}

	public OssFile statFile(String fileName) {
		try {
			return this.statFile(this.ossProperties.getBucketName(), fileName);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	@SneakyThrows
	public OssFile statFile(String bucketName, String fileName) {
		try {
			StatObjectResponse stat = this.client.statObject((StatObjectArgs)((StatObjectArgs.Builder)((StatObjectArgs.Builder)StatObjectArgs.builder().bucket(this.getBucketName(bucketName))).object(fileName)).build());
			OssFile ossFile = new OssFile();
			ossFile.setName(Func.isEmpty(stat.object()) ? fileName : stat.object());
			ossFile.setLink(this.fileLink(ossFile.getName()));
			ossFile.setHash(String.valueOf(stat.hashCode()));
			ossFile.setLength(stat.size());
			ossFile.setPutTime(DateUtil.toDate(stat.lastModified().toLocalDateTime()));
			ossFile.setContentType(stat.contentType());
			return ossFile;
		} catch (Throwable var5) {
			throw var5;
		}
	}

	public String filePath(String fileName) {
		return this.getBucketName().concat("/").concat(fileName);
	}

	public String filePath(String bucketName, String fileName) {
		return this.getBucketName(bucketName).concat("/").concat(fileName);
	}

	public String fileLink(String fileName) {
		try {
			return this.getEndpoint().concat("/").concat(this.getBucketName()).concat("/").concat(fileName);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	public String fileLink(String bucketName, String fileName) {
		try {
			return this.getEndpoint().concat("/").concat(this.getBucketName(bucketName)).concat("/").concat(fileName);
		} catch (Throwable var4) {
			throw var4;
		}
	}

	public BladeFile putFile(MultipartFile file) {
		try {
			return this.putFile(this.ossProperties.getBucketName(), file.getOriginalFilename(), file);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	public BladeFile putFile(String fileName, MultipartFile file) {
		try {
			return this.putFile(this.ossProperties.getBucketName(), fileName, file);
		} catch (Throwable var4) {
			throw var4;
		}
	}

	public BladeFile putFile(String fileName, MultipartFile file,String type) {
		try {
			return this.putFile(this.ossProperties.getBucketName(), fileName, file);
		} catch (Throwable var4) {
			throw var4;
		}
	}

	@SneakyThrows
	public BladeFile putFile(String bucketName, String fileName, MultipartFile file) {
		try {
			return this.putFile(bucketName, file.getOriginalFilename(), file.getInputStream());
		} catch (Throwable var5) {
			throw var5;
		}
	}

	public BladeFile putFile(String fileName, InputStream stream) {
		try {
			return this.putFile(this.ossProperties.getBucketName(), fileName, stream);
		} catch (Throwable var4) {
			throw var4;
		}
	}

	public BladeFile putFile(String bucketName, String fileName, InputStream stream) {
		try {
			return this.putFile(bucketName, fileName, stream, "application/octet-stream");
		} catch (Throwable var5) {
			throw var5;
		}
	}

	public BladeFile putFile(String bucketName, String fileName, InputStream stream, String contentType) {
		try {
			this.makeBucket(bucketName);
			String originalName = fileName;
			if(!fileName.contains("upload/")){
				fileName = this.getFileName(fileName);
			}

			try {
				this.client.putObject((PutObjectArgs)((PutObjectArgs.Builder)((PutObjectArgs.Builder)PutObjectArgs.builder().bucket(this.getBucketName(bucketName))).object(fileName)).stream(stream, (long)stream.available(), -1L).contentType(contentType).build());
			} catch (Exception var16) {
				var16.printStackTrace();
			} finally {
				try {
					if (stream != null) {
						stream.close();
					}
				} catch (Exception var15) {
					var15.printStackTrace();
				}

			}

			BladeFile file = new BladeFile();
			if(!fileName.contains("upload/")){
				file.setOriginalName(originalName);
			}else{
				file.setOriginalName(bucketName+"/"+originalName);
			}
			file.setName(fileName);
			file.setDomain(this.getOssHost(bucketName));
			file.setLink(this.fileLink(bucketName, fileName));
			return file;
		} catch (Throwable var18) {
			throw var18;
		}
	}

	public void removeFile(String fileName) {
		try {
			this.removeFile(this.ossProperties.getBucketName(), fileName);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	@SneakyThrows
	public void removeFile(String bucketName, String fileName) {
		try {
			this.client.removeObject((RemoveObjectArgs)((RemoveObjectArgs.Builder)((RemoveObjectArgs.Builder)RemoveObjectArgs.builder().bucket(this.getBucketName(bucketName))).object(fileName)).build());
		} catch (Throwable var4) {
			throw var4;
		}
	}

	public void removeFiles(List<String> fileNames) {
		try {
			this.removeFiles(this.ossProperties.getBucketName(), fileNames);
		} catch (Throwable var3) {
			throw var3;
		}
	}

	public void removeFiles(String bucketName, List<String> fileNames) {
		try {
			Stream<DeleteObject> stream = fileNames.stream().map(DeleteObject::new);
			MinioClient var10000 = this.client;
			RemoveObjectsArgs.Builder var10001 = (RemoveObjectsArgs.Builder)RemoveObjectsArgs.builder().bucket(this.getBucketName(bucketName));
			stream.getClass();
			var10000.removeObjects((RemoveObjectsArgs)var10001.objects(stream::iterator).build());
		} catch (Throwable var4) {
			throw var4;
		}
	}

	public InputStream statFileStream(String fileName) {
		return this.statFileStream(this.ossProperties.getBucketName(), fileName);
	}

	@SneakyThrows
	public InputStream statFileStream(String bucketName, String fileName) {
		try {
			return this.client.getObject((GetObjectArgs)((GetObjectArgs.Builder)((GetObjectArgs.Builder)GetObjectArgs.builder().bucket(this.getBucketName(bucketName))).object(fileName)).build());
		} catch (Throwable var4) {
			throw var4;
		}
	}

	private String getBucketName() {
		return this.getBucketName(this.ossProperties.getBucketName());
	}

	private String getBucketName(String bucketName) {
		return this.ossRule.bucketName(bucketName);
	}

	private String getFileName(String originalFilename) {
		return this.ossRule.fileName(originalFilename);
	}

	@SneakyThrows
	public String getPresignedObjectUrl(String bucketName, String fileName, Integer expires) {
		try {
			return this.client.getPresignedObjectUrl((GetPresignedObjectUrlArgs)((GetPresignedObjectUrlArgs.Builder)((GetPresignedObjectUrlArgs.Builder)GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(this.getBucketName(bucketName))).object(fileName)).expiry(expires).build());
		} catch (Throwable var5) {
			throw var5;
		}
	}

	public String getPolicyType(PolicyType policyType) {
		return getPolicyType(this.getBucketName(), policyType);
	}

	public static String getPolicyType(String bucketName, PolicyType policyType) {
		StringBuilder builder = new StringBuilder();
		builder.append("{\n");
		builder.append("    \"Statement\": [\n");
		builder.append("        {\n");
		builder.append("            \"Action\": [\n");
		switch (policyType) {
			case WRITE:
				builder.append("                \"s3:GetBucketLocation\",\n");
				builder.append("                \"s3:ListBucketMultipartUploads\"\n");
				break;
			case READ_WRITE:
				builder.append("                \"s3:GetBucketLocation\",\n");
				builder.append("                \"s3:ListBucket\",\n");
				builder.append("                \"s3:ListBucketMultipartUploads\"\n");
				break;
			default:
				builder.append("                \"s3:GetBucketLocation\"\n");
		}

		builder.append("            ],\n");
		builder.append("            \"Effect\": \"Allow\",\n");
		builder.append("            \"Principal\": \"*\",\n");
		builder.append("            \"Resource\": \"arn:aws:s3:::");
		builder.append(bucketName);
		builder.append("\"\n");
		builder.append("        },\n");
		if (PolicyType.READ.equals(policyType)) {
			builder.append("        {\n");
			builder.append("            \"Action\": [\n");
			builder.append("                \"s3:ListBucket\"\n");
			builder.append("            ],\n");
			builder.append("            \"Effect\": \"Deny\",\n");
			builder.append("            \"Principal\": \"*\",\n");
			builder.append("            \"Resource\": \"arn:aws:s3:::");
			builder.append(bucketName);
			builder.append("\"\n");
			builder.append("        },\n");
		}

		builder.append("        {\n");
		builder.append("            \"Action\": ");
		switch (policyType) {
			case WRITE:
				builder.append("[\n");
				builder.append("                \"s3:AbortMultipartUpload\",\n");
				builder.append("                \"s3:DeleteObject\",\n");
				builder.append("                \"s3:ListMultipartUploadParts\",\n");
				builder.append("                \"s3:PutObject\"\n");
				builder.append("            ],\n");
				break;
			case READ_WRITE:
				builder.append("[\n");
				builder.append("                \"s3:AbortMultipartUpload\",\n");
				builder.append("                \"s3:DeleteObject\",\n");
				builder.append("                \"s3:GetObject\",\n");
				builder.append("                \"s3:ListMultipartUploadParts\",\n");
				builder.append("                \"s3:PutObject\"\n");
				builder.append("            ],\n");
				break;
			default:
				builder.append("\"s3:GetObject\",\n");
		}

		builder.append("            \"Effect\": \"Allow\",\n");
		builder.append("            \"Principal\": \"*\",\n");
		builder.append("            \"Resource\": \"arn:aws:s3:::");
		builder.append(bucketName);
		builder.append("/*\"\n");
		builder.append("        }\n");
		builder.append("    ],\n");
		builder.append("    \"Version\": \"2012-10-17\"\n");
		builder.append("}\n");
		return builder.toString();
	}

	public String getOssHost(String bucketName) {
		return this.getEndpoint() + "/" + this.getBucketName(bucketName);
	}

	public String getOssHost() {
		return this.getOssHost(this.ossProperties.getBucketName());
	}

	public String getEndpoint() {
		return StringUtil.isBlank(this.ossProperties.getTransformEndpoint()) ? this.ossProperties.getEndpoint() : this.ossProperties.getTransformEndpoint();
	}

	public MinioTemplate(final MinioClient client, final OssRule ossRule, final OssProperties ossProperties) {
		this.client = client;
		this.ossRule = ossRule;
		this.ossProperties = ossProperties;
	}
}
