package com.platform.modules.live.controller;

import com.platform.common.annotation.SysLog;
import com.platform.common.utils.FileUtils;
import com.platform.common.utils.R;
import com.platform.common.utils.RedisKeys;
import com.platform.common.utils.RedisUtils;
import com.platform.modules.live.service.LiveMultimediaSyncService;
import com.platform.modules.plm.entity.PlmChunkEntity;
import com.platform.modules.plm.util.MateriaFileProperties;
import com.platform.modules.plm.util.MaterialUtils;
import com.platform.modules.video.service.RealPathResolver;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RestController
@Api(value = "资源上传", tags = "资源上传")
@Slf4j
public class MediaUploadController {
	
	@Autowired
	private MateriaFileProperties materiaFileProperties;
	@Autowired
	private RealPathResolver realPathResolver;
	@Autowired
	private RedisUtils redisUtils;
	
	@SysLog("资源上传")
	@PostMapping("/common/upload_media")
	@ApiOperation("资源上传")
	@ApiImplicitParams({
		@ApiImplicitParam(name = "materialFile", value = "上传文件",  paramType = "update", dataType = "file")})
	@ApiResponses({@ApiResponse(code = HttpStatus.SC_OK, message = "success")})
	public R save(@RequestParam("materialFile") MultipartFile materialFile){
		try {
			String newCoverName = FileUtils.createFileName() + "." + FileUtils.getSuffix(materialFile.getOriginalFilename());
			String serverCoverPath = materiaFileProperties.getMediaPath() + "/" + MaterialUtils.getDateDir() +"/" + newCoverName;
	        String newCoverPath = materiaFileProperties.getMateriaPath() + serverCoverPath;
	        FileUtils.copy(materialFile.getInputStream(), realPathResolver.get(newCoverPath));
	        return R.ok("资源上传成功").put("fileUrl", serverCoverPath);
		} catch (Exception e) {
			
			return R.error("资源上传失败");
		}
	}

	@PostMapping("/common/upload_media/chunk")
	@RequiresPermissions(value = {"live:multimedia:save", "live:multimedia:update"}, logical = Logical.OR)
	public R uploadChunk(PlmChunkEntity chunk) {
		if (null==chunk || null==chunk.getFile() || StringUtils.isBlank(chunk.getIdentifier())
				|| null==chunk.getChunkNumber()) {
			return R.error("缺少必要参数");
		}
		String key = RedisKeys.getUploadMediaKey() + chunk.getIdentifier();
		String field = chunk.getIdentifier()+"#"+chunk.getChunkNumber();
		// 续传判断
		if (redisUtils.hexists(key, field)) {
			return R.ok("文件块上传成功");
		}
		MultipartFile file = chunk.getFile();
		String uploadFolder = materiaFileProperties.getMateriaPath() + materiaFileProperties.getMediaPath() + "/" +
				MaterialUtils.getDateDir() +"/";
		try {
			byte[] bytes = file.getBytes();
			Path path = Paths.get(MaterialUtils.generatePath(uploadFolder, chunk));
			//文件写入指定路径
			Files.write(path, bytes);
			// Redis状态存储
			redisUtils.hset(key, field, field);
			return R.ok("文件块上传成功");
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("系统异常");
		}
	}

	@GetMapping("/common/upload_media/chunk")
	@RequiresPermissions(value = {"live:multimedia:save", "live:multimedia:update"}, logical = Logical.OR)
	public R checkChunk(PlmChunkEntity chunk, HttpServletResponse response) {
		String key = chunk.getIdentifier()+"#"+chunk.getChunkNumber();
		String desc = "文件已存在";
		if (!redisUtils.hexists(RedisKeys.getUploadMediaKey() + chunk.getIdentifier(), key)) {
			response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
			desc = "文件不存在";
		}
		return R.ok(desc);
	}

	@PostMapping("/common/upload_media/merge")
	@RequiresPermissions(value = {"live:multimedia:save", "live:multimedia:update"}, logical = Logical.OR)
	public R mergeFile(String filename, String identifier) {
		String uploadFolder = materiaFileProperties.getMateriaPath() + materiaFileProperties.getMediaPath() + "/" +
				MaterialUtils.getDateDir();
		String file = uploadFolder + "/" + identifier + "/" + filename;
		String folder = uploadFolder + "/" + identifier;
		try {
			MaterialUtils.merge(file, folder, filename);
			redisUtils.delete(RedisKeys.getUploadMediaKey() + identifier);
		} catch (Exception e) {
			e.printStackTrace();
			// 合并异常后，分片数据可能全部丢失
			redisUtils.delete(RedisKeys.getUploadMediaKey() + identifier);
			return R.error("文件上传失败");
		}
		return R.ok("文件上传成功");
	}

}
