package org.security.imagePlatformDock.service.impl;

import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.security.common.util.SetFilePermission;
import org.security.common.utils.InputStreamAESUtil;
import org.security.config.ImagePlateFormDockProperties;
import org.security.ht.vo.common.UploadVO;
import org.security.imagePlatformDock.entity.UploadFileRecord;
import org.security.imagePlatformDock.imagePlateform.SunECMClient;
import org.security.imagePlatformDock.service.IUploadFileRecordService;
import org.security.imagePlatformDock.service.IUploadFileService;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

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

/**
 * @author ：wzf
 * @since ：Created in 2022/9/6 16:36
 */
@Service
@Slf4j
@AllArgsConstructor
public class UploadFileServiceImpl implements IUploadFileService {

	private SunECMClient sunECMClient;
	private final IUploadFileRecordService uploadFileRecordService;
	private final ImagePlateFormDockProperties imagePlateFormDockProperties;

	@Override
	public R<UploadVO> sendImagePlateFormDock(MultipartFile file, String groupName, String fileType, Boolean encrypt){
		log.info("------------------文件上传本地服务器开始------------------");
		log.info("上传文件对象:[{}],文件分组名称:[{}],文件类型:[{}],是否加密:[{}]",file,groupName,fileType,encrypt);
		encrypt = Func.isNull(encrypt) ? false : encrypt;
		//将文件存储在本地
		String fileName = DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss").concat("-").concat(file.getOriginalFilename());
		String filePath = imagePlateFormDockProperties.getService_path();
		File saveDir = new File(filePath).getAbsoluteFile();
		if (!saveDir.exists()) {
			saveDir.mkdir();
		}
		File dest = new File( saveDir + "/" + fileName);
		log.info("文件路径:[{}]",dest);
		dest.setReadable(true);
		InputStream encryptedStream = null;
		FileOutputStream fileOutputStream = null;
		InputStream fileInputStream = null;
		try {
			fileInputStream = file.getInputStream();
			encryptedStream = encrypt ? InputStreamAESUtil.encryptStream(fileInputStream) : fileInputStream;
			fileOutputStream = new FileOutputStream(dest);
			byte[] buffer = new byte[1024];
			int r;
			while ((r = encryptedStream.read(buffer)) > 0) {
				fileOutputStream.write(buffer, 0, r);
			}
			fileOutputStream.flush();
			encryptedStream.close();
			fileOutputStream.close();
			SetFilePermission.setPermission(dest.getAbsolutePath());
			log.info("文件上传本地成功");
			log.info("------------------文件上传本地服务器结束------------------");
		} catch (Exception e) {
			log.error("文件上传本地失败" + e);
			e.printStackTrace();
			if (null != fileInputStream) {
				try {
					fileInputStream.close();
				} catch (IOException ex) {
					e.printStackTrace();
				}
			}
			if (null != encryptedStream) {
				try {
					encryptedStream.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			if (null != fileOutputStream) {
				try {
					fileOutputStream.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
			return R.fail(e.getMessage());
		}
		//将文件信息告知影像平台
		UploadFileRecord uploadFileRecord = sunECMClient.uploadSingle(fileName, filePath, groupName, fileType);
		//将上传记录放入影像平台流水记录表
		log.info("将附件上传影像平台记录保存至影像平台流水记录表中，记录信息:{[]}" + uploadFileRecord);
		boolean b = uploadFileRecordService.save(uploadFileRecord);
		//上传影像平台成功
		if ("1".equals(uploadFileRecord.getUploadState()) && b) {
			return R.data(UploadVO.builder()
				.name(fileName)
				.contentId(uploadFileRecord.getContentId())
				.busiBeginDate(uploadFileRecord.getBusiBeginDate())
				.fileType(StringUtils.substring(fileName, fileName.lastIndexOf('.') + 1))
				.url(dest.getPath())
				.groupName(groupName)
				.encrypt(encrypt)
				.build());
		}//上传影像平台失败或上传影像平台记录保存失败
		else {
			log.info("上传影像平台失败或上传影像平台记录保存失败，上传内容:{[]}" + b);
			return R.fail("文件上传影像平台失败");
		}
	}

	@Override
	public String getData(String busiBeginDate, String contentId,String fileName) throws IOException {
		return sunECMClient.getFileData(busiBeginDate,contentId,fileName);
	}

	@Override
	public List<UploadVO> sendImagesPlateFormDock(List<MultipartFile> files, String groupName, String fileType, Boolean encrypt) {
		ArrayList<UploadVO> vos = new ArrayList<>();
		if (Func.isNotEmpty(files)){
			files.forEach(item->{
				R<UploadVO> uploadVOR = this.sendImagePlateFormDock(item, groupName, fileType, encrypt);
				if (Func.isNotEmpty(uploadVOR.getData())){
					vos.add(uploadVOR.getData());
				}
			});
		}
		return vos;
	}

	@Override
	public R removeFileData(String busiBeginDate, String contentId) {
		return sunECMClient.removeFileData(busiBeginDate,contentId);
	}
}
