package com.zjty.tynotes.fs.subject.controller;

import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSBuckets;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.gridfs.model.GridFSUploadOptions;
import com.zjty.tynotes.fs.subject.entity.FsResponse;
import com.zjty.tynotes.misc.config.AutoDocument;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author LJJ cnljj1995@gmail.com
 * on 2019-05-29
 */

@RestController
@RequestMapping("/files")
@AutoDocument
@Slf4j
@Api(tags = "文件下载下载接口", value = "文件上传下载文件的接口")
public class FileController {


    @Autowired
    private MongoDbFactory mongoDbFactory;
    @Autowired
    private GridFsTemplate gridFsTemplate;

    /**
     * 上传文件
     *
     * @param file 文件
     * @return 文件名和文件存储的fileId键值对的Map
     */
    @ApiOperation(value = "上传文件的接口")
    @PostMapping("/upload")
    public ResponseEntity<FsResponse> upload(@RequestParam(value = "file") MultipartFile file) {

        GridFSBucket gridFSBucket = GridFSBuckets.create(mongoDbFactory.getDb());


        Map<String, ObjectId> map = new HashMap<>();
        try {
            InputStream streamToUploadFrom = file.getInputStream();

            Document document = new Document();
            //自定义数据，放入文件真正名和文件类型
            document.append("fileTrueName", file.getOriginalFilename());
            document.append("contentType", file.getContentType());
            //设置chunks长度为358400字节，如果文件过大则创建新的分块
            // 自定义的数据放在metadata里
            GridFSUploadOptions options = new GridFSUploadOptions()
                    .chunkSizeBytes(358400)
                    .metadata(document);

            ObjectId fileId = gridFSBucket.uploadFromStream(UUID.randomUUID().toString(), streamToUploadFrom, options);
            log.info("上传成功，" + "文件名:" + file.getOriginalFilename() + "文件ID:" + fileId);
            map.put(file.getOriginalFilename(), fileId);

            return ResponseEntity.ok(new FsResponse(fileId.toString()));

        } catch (Exception e) {
            log.error("[fs] 文件上传失败");
            return ResponseEntity.ok(new FsResponse("上传失败"));
        }
    }

    /**
     * 通过文件fileId下载文件
     *
     * @param fileId 文件fileId
     * @param response 文件输出流
     */
    @ApiOperation(value = "下载文件的接口")
    @RequestMapping(value = "/download")
    public void downLoadByFileId(@RequestParam(value = "fileId") ObjectId fileId
            , HttpServletRequest request, HttpServletResponse response) {

        GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));


        try {
            //获取回复的输出流
            OutputStream sos = response.getOutputStream();
            //设置编码格式

            response.setCharacterEncoding("UTF-8");
//            response.setHeader("Access-Control-Allow-Origin", "*");
            //设置文件返回类型，为上传文件时获取的文件类型
//             response.setContentType(gridFSFile.getMetadata().get("contentType").toString());
            String fileName = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId))).getMetadata().get("fileTrueName").toString();
            response.addHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName,"UTF-8") + "\"");
            response.setContentType("application/octet-stream;charset=UTF-8");
//            response.setHeader("Access-Control-Allow-Origin", request.getHeader("*"));
//            response.setHeader("Access-Control-Allow-Credentials", "true");
//            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE");
//            response.setHeader("Access-Control-Max-Age", "3600");
//            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

            GridFSBucket bucket = GridFSBuckets.create(mongoDbFactory.getDb());
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            // 获取Mongodb中文件的缓存输出流
            bucket.downloadToStream(gridFSFile.getId(), sos);
            //将查询到的数据放入到输出流sos中
            sos.flush();
            sos.close();

        } catch (Exception e) {
            log.error("下载文件失败，失败原因：{}", e.getMessage());
        }


    }



}
