package com.jiayue.ipfcst.ftpsftp.controller;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
import com.jiayue.ipfcst.ftpsftp.dto.FTPSFTPDto;
import com.jiayue.ipfcst.ftpsftp.service.ContinueSFTPService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("SFTP")
@Slf4j
public class SFTPController {
  private String remoteIp;
  private String remotePort;
  private String uploadUserName;
  private String uploadPassword;
  @Autowired
  private final ContinueSFTPService continueSFTPService;

  public SFTPController(ContinueSFTPService continueSFTPService){
    this.continueSFTPService = continueSFTPService;
  }
  /**
   * 连接SFTP
   * @param ftpsftpDtos
   * @return 返回所有目录
   */
  @PostMapping(value = "/continueSFTP")
  public ResponseVO continueSFTP(@RequestBody FTPSFTPDto ftpsftpDtos) throws IOException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<FTPSFTPDto> FTPSFTPDtoList = new ArrayList<>();
    try {
      //登陆
      continueSFTPService.login(ftpsftpDtos.getUploadUserName(), ftpsftpDtos.getUploadPassword(), ftpsftpDtos.getRemoteIp(),Integer.parseInt(ftpsftpDtos.getRemotePort()),"");
      //获取目录下所有文件
      ArrayList<ChannelSftp.LsEntry> ftpFileArr= continueSFTPService.listFiles(ftpsftpDtos.getServicePath());
      remoteIp = ftpsftpDtos.getRemoteIp();
      remotePort = ftpsftpDtos.getRemotePort();
      uploadUserName = ftpsftpDtos.getUploadUserName();
      uploadPassword = ftpsftpDtos.getUploadPassword();
      for (int i = 0; i < ftpFileArr.size(); i++) {
        FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
        String name = ftpFileArr.get(i).getFilename();
        SftpATTRS attrs = ftpFileArr.get(i).getAttrs();
        BigDecimal fileSize = new BigDecimal(attrs.getSize());
        String fileSizes = fileSize.divide(new BigDecimal(1024)).divide(new BigDecimal(1024)).setScale(2, BigDecimal.ROUND_CEILING).toString();
        ftpsftpDto.setName(name);
        ftpsftpDto.setJurisdiction(attrs.getPermissionsString());
        if(attrs.isDir()){
          ftpsftpDto.setFileSize("--");
        }else{
          ftpsftpDto.setFileSize(fileSizes+"MB");
        }
        Long time = attrs.getMTime()*1000l;
        ftpsftpDto.setLastModified(sdf.format(time));
        ftpsftpDto.setDirectory(attrs.isDir());
        FTPSFTPDtoList.add(ftpsftpDto);
      }

      return ResponseVO.success(FTPSFTPDtoList);
    }catch (Exception e){
      return ResponseVO.fail("连接失败,请检查配置信息");
    }

  }

  /**
   * 根据传入的路径 返回上一级/进入下一级
   * @param ftpsftpDtos
   * @return
   */
  @PostMapping(value = "/openServicePath")
  public ResponseVO openServicePath(@RequestBody FTPSFTPDto ftpsftpDtos){
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<FTPSFTPDto> FTPSFTPDtoList = new ArrayList<>();
    try{
      ArrayList<ChannelSftp.LsEntry> ftpFileArr =continueSFTPService.listFiles(ftpsftpDtos.getServicePath());
      for (int i = 0; i < ftpFileArr.size(); i++) {
        FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
        String name = ftpFileArr.get(i).getFilename();
        SftpATTRS attrs = ftpFileArr.get(i).getAttrs();
        BigDecimal fileSize = new BigDecimal(attrs.getSize());
        String fileSizes = fileSize.divide(new BigDecimal(1024)).divide(new BigDecimal(1024)).setScale(2, BigDecimal.ROUND_CEILING).toString();
        ftpsftpDto.setName(name);
        ftpsftpDto.setJurisdiction(attrs.getPermissionsString());
        if(attrs.isDir()){
          ftpsftpDto.setFileSize("--");
        }else{
          ftpsftpDto.setFileSize(fileSizes+"MB");
        }
        Long time = attrs.getMTime()*1000l;
        ftpsftpDto.setLastModified(sdf.format(time));
        ftpsftpDto.setDirectory(attrs.isDir());
        FTPSFTPDtoList.add(ftpsftpDto);
      }
      return ResponseVO.success(FTPSFTPDtoList);
    }catch (Exception e){
      return ResponseVO.fail("进入下一级目录失败");
    }
  }

  /**
   * 下载文件
   * @param request
   * @param response
   * @param path 路径
   * @param name 文件名
   * @return
   */
  @PostMapping(value = "/downloadFile")
  public void download(HttpServletRequest request,
                       HttpServletResponse response,
                       String path,
                       String name) throws IOException {
    response.setContentType("text/html;charset=utf-8");
    try {
      request.setCharacterEncoding("UTF-8");
    } catch (UnsupportedEncodingException e) {
      log.error("系统错误：" + e.getMessage(), e);
    }
    try{
      InputStream ins = continueSFTPService.download(path,name);

      BufferedInputStream bins = new BufferedInputStream(ins);
      OutputStream outs = response.getOutputStream();
      BufferedOutputStream bouts = new BufferedOutputStream(outs);
      response.setHeader("Content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(name, "UTF-8"));
      response.setContentType("application/x-msdownload");
      int bytesRead = 0;
      byte[] buffer = new byte[8192];
      while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
        bouts.write(buffer, 0, bytesRead);
      }
      bouts.flush();
      ins.close();
      bins.close();
      bouts.close();
      flush(remoteIp,remotePort, uploadUserName, uploadPassword);
    }catch (Exception e){
      log.error("系统错误：" + e.getMessage(), e);
    }

  }

  @PostMapping(value = "/upload")
  public ResponseVO upload(@RequestParam("path") String path,@RequestParam("file") MultipartFile file){
    try{
      continueSFTPService.upload(path,file.getOriginalFilename(),file.getInputStream());
      FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
      ftpsftpDto.setUploadPassword(uploadPassword);
      ftpsftpDto.setUploadUserName(uploadUserName);
      ftpsftpDto.setRemotePort(remoteIp);
      ftpsftpDto.setRemoteIp(remoteIp);
      ftpsftpDto.setServicePath(path);
      return openServicePath(ftpsftpDto);
    }catch (Exception e){
      return ResponseVO.fail("上传文件失败"+e);
    }
  }

  /**
   * 关闭连接
   * @return
   * @throws IOException
   */
  @GetMapping(value = "/closeContinue")
  public ResponseVO closeContinue() throws IOException {
    try {
      continueSFTPService.logout();
      return ResponseVO.success("连接已关闭");
    }catch (Exception e){
      return ResponseVO.fail("无法关闭连接");
    }

  }

  /**
   * 删除文件
   * @param name 文件名称
   * @param path 服务器路径
   * @return
   */
  @PostMapping(value = "/deleteFile")
  public ResponseVO deleteFile(@RequestParam("name") String name,@RequestParam("path") String path){
    try{
      Boolean flag = false;
      if(path.equals("/")){
        flag = continueSFTPService.delete(path,name);
      }else{
        flag = continueSFTPService.delete(path+File.separator,name);
      }
      if(!flag){
        return  ResponseVO.fail("删除文件失败");
      }
      FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
      ftpsftpDto.setUploadPassword(uploadPassword);
      ftpsftpDto.setUploadUserName(uploadUserName);
      ftpsftpDto.setRemotePort(remoteIp);
      ftpsftpDto.setRemoteIp(remoteIp);
      ftpsftpDto.setServicePath(path);
      return openServicePath(ftpsftpDto);
    }catch (Exception e){
      return ResponseVO.fail("删除文件失败"+e);
    }

  }
  /**
   * 刷新连接
   * @param host ip地址
   * @param port 端口
   * @param userName 用户名
   * @param password 密码
   * @throws IOException
   */
  public void flush(String host, String port, String userName, String password) throws IOException {
    continueSFTPService.logout();
    continueSFTPService.login(userName,password,host,Integer.parseInt(port),"");
  }
}
