import Client from "ssh2-sftp-client";
import { LogWithCurrentTime } from "../util/common.js";

export class SFTPClient {
  options = {};

  constructor() {
    this.client = new Client();
  }

  async connect(options) {
    this.options = options;
    LogWithCurrentTime(`Connecting to ${options.host}:${options.port}`);
    try {
      await this.client.connect(options);
      LogWithCurrentTime("PIX server connected");
    } catch (err) {
      console.error(
        "PIX서버 접속에 실패하였습니다. PIX서버 상태를 확인해주세요.:",
        err
      );
    }
  }

  async disconnect() {
    await this.client.end();
  }

  async checkConnection() {
    try {
      await this.client.list("/");
      return true;
    } catch (error) {
      return false;
    }
  }

  async ensureConnection() {
    if (!(await this.checkConnection())) {
      LogWithCurrentTime("Connection lost. Reconnecting...");
      await this.connect(this.options);
    }
  }

  async getRecentFileName(remoteDir, fileGlob) {
    await this.ensureConnection();
    let fileObjects;
    try {
      fileObjects = await this.client.list(remoteDir, fileGlob);
      fileObjects.sort((a, b) => b.modifyTime - a.modifyTime);
      return fileObjects[0].name;
    } catch (err) {
      console.error("Listing failed:", err);
    }
    return "";
  }

  async uploadFile(localFile, remoteFile) {
    await this.ensureConnection();
    LogWithCurrentTime(`Uploading ${localFile} to ${remoteFile} ...`);
    try {
      await this.client.put(localFile, remoteFile);
    } catch (err) {
      console.error("Uploading failed:", err);
    }
  }

  async downloadFile(remoteFile, localFile) {
    await this.ensureConnection();
    LogWithCurrentTime(`Downloading from ${remoteFile} to ${localFile} ...`);
    try {
      await this.client.fastGet(remoteFile, localFile);
    } catch (err) {
      console.error("Downloading failed:", err);
    }
  }

  async deleteOldFiles(directoryPath, maxFilesToKeep = 0) {
    await this.ensureConnection();
    try {
      const fileList = await this.client.list(directoryPath);
      fileList.sort((a, b) => {
        return (
          new Date(a.modifyTime).getTime() - new Date(b.modifyTime).getTime()
        );
      });

      for (let i = 0; i < fileList.length - maxFilesToKeep; i++) {
        const fileToDelete = `${directoryPath}/${fileList[i].name}`;
        await this.client.delete(fileToDelete);
      }
    } catch (err) {
      console.error("파일을 삭제할 수 없습니다:", err);
    }
  }
}