package cn.com.tenlion.freemarker.controller.apis.templaterecord;

import cn.com.tenlion.freemarker.pojo.dtos.templaterecord.TemplateRecordDTO;
import cn.com.tenlion.freemarker.pojo.vos.templaterecord.TemplateRecordVO;
import cn.com.tenlion.freemarker.service.templaterecord.ITemplateRecordService;
import ink.wgink.annotation.CheckRequestBodyAnnotation;
import ink.wgink.common.base.DefaultBaseController;
import ink.wgink.common.component.SecurityComponent;
import ink.wgink.exceptions.RemoveException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.consts.ISystemConstant;
import ink.wgink.interfaces.manager.IAppManager;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.app.AppToken;
import ink.wgink.pojo.app.AppTokenUser;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.dtos.CurrentUserIdInfoDTO;
import ink.wgink.pojo.result.ErrorResult;
import ink.wgink.pojo.result.SuccessResult;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.ReflectUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.AbstractController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: TemplateRecordController
 * @Description: 模板构建记录
 * @Author: WenG
 * @Date: 2020-05-07 16:50
 * @Version: 1.0
 **/
@Api(tags = ISystemConstant.API_TAGS_SYSTEM_PREFIX + "模板构建记录接口")
@RestController
@RequestMapping(ISystemConstant.API_PREFIX + "/templaterecord")
public class TemplateRecordController extends DefaultBaseController {

    @Autowired
    private ITemplateRecordService templateRecordService;
    @Autowired
    private SecurityComponent securityComponent;

    @ApiOperation(value = "模板构建文件获取", notes = "模板构建文件获取")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateFileType", value = "文件类型", paramType = "path"),
            @ApiImplicitParam(name = "templateRecordId", value = "记录ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping(value = "get/{templateFileType}/{templateRecordId}")
    public void getById(@PathVariable("templateFileType") String templateFileType, @PathVariable("templateRecordId") String templateRecordId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 返回文件
        TemplateRecordDTO dto = templateRecordService.getTemplateRecordById(templateRecordId);
        File file = new File(dto.getTemplateRecordPath());
        String fileName = file.getName();
        String userAgent = request.getHeader("User-Agent").toUpperCase();
        if (userAgent.indexOf("MSIE") > 0 || userAgent.indexOf("Trident") > 0) {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        byte[] data = toByteArray(file);
        response.reset();
        response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", fileName));
        response.addHeader("Content-Length", "" + data.length);
        if ("html".equals(templateFileType)) {
            response.setContentType("text/html;charset=UTF-8");
        }else{
            response.setContentType("application/octet-stream;charset=UTF-8");
        }
        response.setCharacterEncoding("UTF-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        outputStream.write(data);
        outputStream.flush();
        outputStream.close();
        response.flushBuffer();
    }

    @ApiOperation(value = "模板构建Html页面", notes = "模板构建Html页面接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateRecordId", value = "记录ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping(value = "get/html/{templateRecordId}", produces = "text/html")
    public String getHtmlById(@PathVariable("templateRecordId") String templateRecordId) throws Exception {
        TemplateRecordDTO dto = templateRecordService.getTemplateRecordById(templateRecordId);
        File file = new File(dto.getTemplateRecordPath());
        StringBuilder logContent = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null) {
                logContent.append(line).append("\r\n");
            }
        } catch (IOException x) {
            x.printStackTrace();
        }
        return logContent.toString();
    }

    @ApiOperation(value = "模板构建记录详情(通过ID)", notes = "模板构建记录详情(通过ID)接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateRecordId", value = "模板构建记录ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("gettemplaterecordcontentbyid/{templateRecordId}")
    public TemplateRecordDTO getTemplateRecordContentById(@PathVariable("templateRecordId") String templateRecordId) throws SearchException {
        TemplateRecordDTO dto = templateRecordService.getTemplateRecordById(templateRecordId);
        File file = new File(dto.getTemplateRecordPath());
        StringBuilder logContent = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line = null;
            while ((line = reader.readLine()) != null) {
                logContent.append(line).append("\r\n");
            }
        } catch (IOException x) {
            x.printStackTrace();
        }
        dto.setTemplateContentText(logContent.toString());
        return dto;
    }



    @ApiOperation(value = "新增模板构建记录", notes = "新增模板构建记录接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PostMapping("savetemplaterecord")
    @CheckRequestBodyAnnotation
    public SuccessResult saveTemplateRecord(@RequestBody TemplateRecordVO templateRecordVO) throws Exception {
        return templateRecordService.saveTemplateRecord(templateRecordVO);
    }

    @ApiOperation(value = "删除模板构建记录(id列表)", notes = "删除模板构建记录(id列表)接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ID列表，用下划线分隔", paramType = "path", example = "1_2_3")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @DeleteMapping("removetemplaterecord/{ids}")
    public SuccessResult removeTemplateRecord(@PathVariable("ids") String ids) throws RemoveException {
        return templateRecordService.removeTemplateRecord(ids);
    }

    @ApiOperation(value = "修改模板构建记录", notes = "修改模板构建记录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateRecordId", value = "模板构建记录ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @PutMapping("updatetemplaterecord/{templateRecordId}")
    @CheckRequestBodyAnnotation
    public SuccessResult updateTemplateRecord(@PathVariable("templateRecordId") String templateRecordId, @RequestBody TemplateRecordVO templateRecordVO) throws Exception {
        return templateRecordService.updateTemplateRecord(templateRecordId, templateRecordVO);
    }

    @ApiOperation(value = "模板构建记录详情(通过ID)", notes = "模板构建记录详情(通过ID)接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "templateRecordId", value = "模板构建记录ID", paramType = "path")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("gettemplaterecordbyid/{templateRecordId}")
    public TemplateRecordDTO getTemplateRecordById(@PathVariable("templateRecordId") String templateRecordId) throws SearchException {
        return templateRecordService.getTemplateRecordById(templateRecordId);
    }

    @ApiOperation(value = "模板构建记录列表", notes = "模板构建记录列表接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("listtemplaterecord")
    public List<TemplateRecordDTO> listTemplateRecord() throws SearchException {
        Map<String, Object> params = requestParams();
        return templateRecordService.listTemplateRecord(params);
    }

    @ApiOperation(value = "模板构建记录分页列表", notes = "模板构建记录分页列表接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", paramType = "form", dataType = "Integer", defaultValue = "1"),
            @ApiImplicitParam(name = "rows", value = "显示数量", paramType = "form", dataType = "Integer", defaultValue = "20"),
            @ApiImplicitParam(name = "keywords", value = "关键字", paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "startTime", value = "开始时间", paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "form", dataType = "String")
    })
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("listpagetemplaterecord")
    public SuccessResultList<List<TemplateRecordDTO>> listPageTemplateRecord(ListPage page) throws SearchException {
        Map<String, Object> params = requestParams();
        page.setParams(params);
        return templateRecordService.listPageTemplateRecord(page);
    }

    @ApiOperation(value = "当前用户id信息", notes = "当前用户id信息接口")
    @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)})
    @GetMapping("getcurrentuseridinfo")
    public CurrentUserIdInfoDTO getCurrentUserIdInfo() {
        return securityComponent.getCurrentUserIdInfo();
    }

    /**
     * 读取到字节数组
     * @param f 文件对象
     * @return
     * @throws IOException
     */
    private byte[] toByteArray(File f) throws IOException {
        FileChannel channel = null;
        FileInputStream fs = null;
        try {
            fs = new FileInputStream(f);
            channel = fs.getChannel();
            ByteBuffer byteBuffer = ByteBuffer.allocate((int) channel.size());
            while ((channel.read(byteBuffer)) > 0) {
            }
            return byteBuffer.array();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                channel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}