package com.jiayue.ipfcst.ftpsftp.controller;

import com.jiayue.ipfcst.common.core.web.vo.ResponseVO;
import com.jiayue.ipfcst.common.data.entity.UploadURL;
import com.jiayue.ipfcst.ftpsftp.dto.FTPSFTPDto;
import com.jiayue.ipfcst.ftpsftp.service.ContinueFTPService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.FastArrayList;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.transaction.annotation.Transactional;
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("FTP")
@Slf4j
public class FTPController {
  private String remoteIp;
  private String remotePort;
  private String uploadUserName;
  private String uploadPassword;
  @Autowired
  private final ContinueFTPService continueFTPService;

  public FTPController(ContinueFTPService continueFTPService){
    this.continueFTPService = continueFTPService;
  }
  /**
   * 连接FTP
   * @param ftpsftpDtos
   * @return 返回所有目录
   */
  @PostMapping(value = "/continueFTP")
  public ResponseVO continueFTP(@RequestBody FTPSFTPDto ftpsftpDtos) throws IOException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<FTPSFTPDto> FTPSFTPDtoList = new ArrayList<>();
    try {
      //登陆
      continueFTPService.initFtpClient(ftpsftpDtos.getRemoteIp(), Integer.parseInt(ftpsftpDtos.getRemotePort()), ftpsftpDtos.getUploadUserName(), ftpsftpDtos.getUploadPassword());
      //获取目录下所有文件
      FTPFile[] files =continueFTPService.listFiles(ftpsftpDtos.getServicePath());
      remoteIp = ftpsftpDtos.getRemoteIp();
      remotePort = ftpsftpDtos.getRemotePort();
      uploadUserName = ftpsftpDtos.getUploadUserName();
      uploadPassword = ftpsftpDtos.getUploadPassword();
      for (int i = 0; i < files.length; i++) {
        FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
        String name = new String(files[i].getName().getBytes("iso-8859-1"),"UTF-8");
        String s = files[i].getRawListing();
        String subStrings = s.substring(0,10);
        BigDecimal fileSize = new BigDecimal(files[i].getSize());
        String fileSizes = fileSize.divide(new BigDecimal(1024)).divide(new BigDecimal(1024)).setScale(2, BigDecimal.ROUND_CEILING).toString();
        Long lastTime = files[i].getTimestamp().getTimeInMillis()+files[i].getTimestamp().getTimeZone().getOffset(0);

        ftpsftpDto.setName(name);
        if(files[i].isFile()){
          ftpsftpDto.setFileSize(fileSizes+"MB");
        }else{
          ftpsftpDto.setFileSize("--");
        }
        ftpsftpDto.setLastModified(sdf.format(lastTime));
        ftpsftpDto.setJurisdiction(subStrings);
        ftpsftpDto.setDirectory(files[i].isDirectory());
        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{
      FTPFile[] files =continueFTPService.listFiles(ftpsftpDtos.getServicePath());
      for (int i = 0; i < files.length; i++) {
        FTPSFTPDto ftpsftpDto = new FTPSFTPDto();
        String name = new String(files[i].getName().getBytes("iso-8859-1"),"UTF-8");

        String s = files[i].getRawListing();
        String subStrings = s.substring(0,10);
        BigDecimal fileSize = new BigDecimal(files[i].getSize());
        String fileSizes = fileSize.divide(new BigDecimal(1024)).divide(new BigDecimal(1024)).setScale(2, BigDecimal.ROUND_CEILING).toString();
        Long lastTime = files[i].getTimestamp().getTimeInMillis()+files[i].getTimestamp().getTimeZone().getOffset(0);

        ftpsftpDto.setName(name);
        if(files[i].isFile()){
          ftpsftpDto.setFileSize(fileSizes);
        }else{
          ftpsftpDto.setFileSize("--");
        }
        ftpsftpDto.setLastModified(sdf.format(lastTime));
        ftpsftpDto.setJurisdiction(subStrings);
        ftpsftpDto.setDirectory(files[i].isDirectory());
        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 = continueFTPService.downLoad(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{
      continueFTPService.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 {
      continueFTPService.close();
      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 = continueFTPService.delete(path,name);
      }else{
       flag = continueFTPService.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 {
    continueFTPService.close();
    continueFTPService.initFtpClient(host,Integer.parseInt(port),userName,password);
  }
}
