declare module "ssh2" {
  import type { EventEmitter } from "node:events";
  import type { Stats } from "node:fs";

  export interface ConnectConfig {
    host: string;
    port?: number;
    username: string;
    password?: string;
    privateKey?: Buffer | string;
    passphrase?: string;
    tryKeyboard?: boolean;
    readyTimeout?: number;
    keepaliveInterval?: number;
    keepaliveCountMax?: number;
    hostVerifier?: (key: Buffer) => boolean;
  }

  export interface ClientChannel extends EventEmitter {
    stderr: EventEmitter;
    close(): void;
    signal(signal: string): void;
  }

  export interface SFTPWrapper {
    readFile(path: string, callback: (error: Error | undefined, data: Buffer) => void): void;
    writeFile(path: string, data: Buffer, callback: (error?: Error) => void): void;
    open(path: string, flags: string, callback: (error: Error | undefined, handle: Buffer) => void): void;
    close(handle: Buffer, callback: (error?: Error) => void): void;
    mkdir(path: string, callback: (error?: Error) => void): void;
    stat(path: string, callback: (error: Error | undefined, stats: Stats) => void): void;
    rename(oldPath: string, newPath: string, callback: (error?: Error) => void): void;
    unlink(path: string, callback: (error?: Error) => void): void;
    end(): void;
    ext_openssh_rename?(oldPath: string, newPath: string, callback: (error?: Error) => void): void;
  }

  export class Client extends EventEmitter {
    connect(config: ConnectConfig): this;
    exec(
      command: string,
      callback: (error: Error | undefined, channel: ClientChannel) => void,
    ): void;
    sftp(callback: (error: Error | undefined, sftp: SFTPWrapper) => void): void;
    end(): this;
    destroy(): this;
  }
}
