package com.bcxin.identify.util.file.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.common.comm.Protocol;
import com.aliyun.oss.model.*;
import com.bcxin.identify.util.codes.CommonConst;
import com.bcxin.identify.util.sys.ConfigUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Objects;

/**
 * 执行上传阿里OSS
 * @author lp
 */
public class OSSServiceExecutor implements OSSService {

	private String server;
	private String bucketName;
	private final String PROTOCOL_STRING = Protocol.HTTP + "://";
	private static final Logger logger = LoggerFactory.getLogger(OSSServiceExecutor.class);

	public OSSServiceExecutor(String envi) {
		if (Objects.equals(envi, ConfigUtil.getValue(CommonConst.ENVI_PROD))) {
			server = this.PROTOCOL_STRING + ConfigUtil.getValue(CommonConst.HUAWEI_OSS_BUCKETNAME_PROD) + CommonConst.DOT + ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS) + CommonConst.SLASH;
			bucketName = ConfigUtil.getValue(CommonConst.HUAWEI_OSS_BUCKETNAME_PROD);
		} else {
			server = this.PROTOCOL_STRING + ConfigUtil.getValue(CommonConst.HUAWEI_OSS_BUCKETNAME_TEST) + CommonConst.DOT + ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS) + CommonConst.SLASH;
			bucketName = ConfigUtil.getValue(CommonConst.HUAWEI_OSS_BUCKETNAME_TEST);
		}
	}

	@Override
	public OSSClient getClient() {
		return new OSSClient(ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS), ConfigUtil.getValue(CommonConst.HUAWEI_OSS_ACCESSID), ConfigUtil.getValue(CommonConst.HUAWEI_OSS_ACCESSKEY));
	}

	@Override
	public String getServer(){
		return this.server;
	}

	@Override
	public void createDirectory(String directoryName) {
		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(0L);
		byte[] buffer = new byte[0];
		ByteArrayInputStream in = new ByteArrayInputStream(buffer);
		OSS ossClient = getClient();
		ossClient.putObject(bucketName, directoryName
				+ "/", in, objectMeta);
	}

	@Override
	public OSSResultInfo createDirectory(String directoryName,
			ObjectMetadata meta) {
		ObjectMetadata objectMeta = new ObjectMetadata();
		objectMeta.setContentLength(0L);
		byte[] buffer = new byte[0];
		ByteArrayInputStream in = new ByteArrayInputStream(buffer);
		OSS ossClient = getClient();
		PutObjectResult result = ossClient.putObject(bucketName, directoryName
				+ CommonConst.SLASH, in, objectMeta);
		OSSResultInfo resultInfo = new OSSResultInfo();
		resultInfo.setBucketName(bucketName);
		resultInfo.setName(directoryName);
		resultInfo.setTag(result.getETag());
		resultInfo.setUrl(formatUrl(this.PROTOCOL_STRING + bucketName + CommonConst.DOT
					+ ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS) + CommonConst.SLASH + directoryName + CommonConst.SLASH));
		return resultInfo;
	}

	@Override
	public boolean deleteDirectory(String directoryName) {
		OSS ossClient = getClient();
		try {
			if (directoryName.lastIndexOf("/") != directoryName.length() - 1) {
				ossClient.deleteObject(bucketName, directoryName + "/");
			} else {
				ossClient.deleteObject(bucketName, directoryName);
			}
			return true;
		} catch (OSSException e) {
			if (e.getErrorCode().equals("NoSuchKey")) {
				return true;
			}
			throw new OSSException("", e);
		}
	}

	@Override
	public boolean deleteFile(String fileName) {
		OSS ossClient = getClient();
		try {
			ossClient.deleteObject(bucketName, fileName);
			return true;
		} catch (OSSException e) {
			if (e.getErrorCode().equals("NoSuchKey")) {
				return true;
			}
			throw new OSSException("", e);
		}
	}

	@Override
	public boolean isExitsDirectory(String directoryName) {
		OSS ossClient = getClient();
		boolean result;
		if (directoryName.lastIndexOf("/") != directoryName.length() - 1) {
			result = ossClient.doesObjectExist(bucketName, directoryName + "/");
		} else {
			result = ossClient.doesObjectExist(bucketName, directoryName);
		}
		return result;
	}

	@Override
	public boolean isExitsFile(String file) {
		return getClient().doesObjectExist(bucketName, file);
	}

	@Override
	public void put(String url, InputStream input) {
		putObject(url, input);
	}

	private void putObject(String url, InputStream input) {
		OSSClient ossClient = getClient();
		try {
			url = url.indexOf("/") == 0 ? url.substring(1) : url;
			boolean condition = (url.contains("https://"))
					|| (url.contains("http://"));
			String tmpServer = !condition ? null : url.replace("https://", "")
					.replace("http://", "").replace("//", "/").split("/")[0];
			String key = url.replace(server, "").replace("//", "/");
			if ((tmpServer == null) || (server.contains(tmpServer))) {
				ObjectMetadata objMeta = OSSUtil.getObjectMetadata(key);
				PutObjectRequest obj = new PutObjectRequest(bucketName, key, input,objMeta);
				logger.debug("执行文件OSS文件上传");
				ossClient.putObject(obj);
				logger.debug("执行文件OSS文件上传成功");
			}
		} catch(Exception e){
			e.printStackTrace();
			logger.debug("exception:传入的URL地址与当前服务器地址或bucketName不一致");
		} finally {
			ossClient.shutdown();
		}
	}

	@Override
	public File get(String url, String saveFileName) {
		String key = url.replace(server, "").replace("//", "/");
		File file = new File(saveFileName);
		OSS ossClient = getClient();
		ossClient.getObject(new GetObjectRequest(bucketName, key), file);
		return file;
	}

	@Override
	public OSSResultObject get(String url) {
		url = url.indexOf("/") == 0 ? url.substring(1) : url;
		boolean condition = (url.contains("https://"))
				|| (url.contains("http://"));
		String tmpServer = !condition ? null : url.replace("https://", "")
				.replace("http://", "").replace("//", "/").split("/")[0];
		String key = url.replace(server, "").replace("//", "/");
		if ((tmpServer == null) || (server.contains(tmpServer))) {
			OSSObject obj = getClient().getObject(bucketName, key);
			OSSResultObject subobj = new OSSResultObject();
			subobj.setBucketName(obj.getBucketName());
			subobj.setKey(key);
			subobj.setFileType(OSSUtil.getFileType(url));
			subobj.setName(OSSUtil.getName(url));
			subobj.setObjectContent(obj.getObjectContent());
			subobj.setMetadata(obj.getObjectMetadata());
			subobj.setUrl(formatUrl(server + key));
			subobj.setServerAddress(ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS));
			subobj.setHttpUrl(subobj.getUrl().replace("https://", "http://"));
			return subobj;
		}
		
		throw new OSSException("传入的URL地址与当前服务器地址或bucketName不一致:" + tmpServer);
	}

	@Override
	public ObjectMetadata getFileMetadata(String url) {
		OSS ossClient = getClient();
		url = url.indexOf("/") == 0 ? url.substring(1) : url;
		boolean condition = (url.contains("https://"))
				|| (url.contains("http://"));
		String tmpServer = !condition ? null : url.replace("https://", "")
				.replace("http://", "").replace("//", "/").split("/")[0];
		String key = url.replace(server, "").replace("//", "/");
		if ((tmpServer == null) || (server.contains(tmpServer))) {
			ObjectMetadata objMeta = ossClient.getObjectMetadata(bucketName,
					key);
			
			return objMeta;
		}
		
		throw new OSSException("传入的URL地址与当前服务器地址或bucketName不一致:" + tmpServer);
	}


	@Override
	public String getBucketUrl() {
		return bucketName + "." + ConfigUtil.getValue(CommonConst.HUAWEI_OSS_SERVERADDRESSS);
	}

	@Override
	public void copy(String srcPath, String desPath) {
		getClient().copyObject(bucketName, getKey(srcPath), bucketName,
				getKey(desPath));
	}

	@Override
	public void copy(String srcPath, String desPath, ObjectMetadata newMeta) {
		OSS ossClient = getClient();
		CopyObjectRequest obj = new CopyObjectRequest(bucketName,
				getKey(srcPath), bucketName, getKey(desPath));
		obj.setNewObjectMetadata(newMeta);
		ossClient.copyObject(obj);
	}

	@Override
	public void upMeta(String url, ObjectMetadata meta) {
		copy(url, url, meta);
	}

	private String formatUrl(String url) {
		return this.PROTOCOL_STRING
				+ url.replace(this.PROTOCOL_STRING, "").replace("http://", "")
						.replace("//", "/");
	}

	private String getKey(String url) {
		url = url.indexOf("/") == 0 ? url.substring(1) : url;
		String key = url.replace(server, "").replace("//", "/");
		return key;
	}
}
