import { spawn } from 'node:child_process';
import { Server } from 'node:net';
import type { ConnectionDetails, TunnelConfig } from '../../types/pg/tunnel.js';
import { getPsqlConfigs, sshTunnel } from './bastion.js';
/**
 * A small wrapper around tunnel-ssh so that other code doesn't have to worry about whether there is or is not a tunnel.
 */
export declare class Tunnel {
    private readonly bastionTunnel;
    private readonly events;
    /**
     * Creates a new Tunnel instance.
     *
     * @param bastionTunnel - The SSH tunnel server or void if no tunnel is needed
     */
    constructor(bastionTunnel: Server | void);
    /**
     * Creates and connects to an SSH tunnel.
     *
     * @param connectionDetails - The database connection details with attachment information
     * @param tunnelConfig - The tunnel configuration object
     * @param tunnelFn - The function to create the SSH tunnel (default: sshTunnel)
     * @returns Promise that resolves to a new Tunnel instance
     */
    static connect(connectionDetails: ConnectionDetails, tunnelConfig: TunnelConfig, tunnelFn: typeof sshTunnel): Promise<Tunnel>;
    /**
     * Closes the tunnel if it exists, or emits a fake close event if no tunnel is needed.
     *
     * @returns void
     */
    close(): void;
    /**
     * Waits for the tunnel to close.
     *
     * @returns Promise that resolves when the tunnel closes
     * @throws Error if the secure tunnel fails
     */
    waitForClose(): Promise<void>;
}
export default class PsqlService {
    private readonly connectionDetails;
    private readonly getPsqlConfigsFn;
    private readonly spawnFn;
    private readonly tunnelFn;
    constructor(connectionDetails: ConnectionDetails, getPsqlConfigsFn?: typeof getPsqlConfigs, spawnFn?: typeof spawn, tunnelFn?: typeof sshTunnel);
    /**
     * Executes a file containing SQL commands using the instance's database connection details.
     * It uses the `getPsqlConfigs` function to get the configuration for the database and the tunnel,
     * and then calls the `runWithTunnel` function to execute the file.
     *
     * @param file - The path to the SQL file to execute
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Promise that resolves to the query result as a string
     */
    execFile(file: string, psqlCmdArgs?: string[]): Promise<string>;
    /**
     * Executes a PostgreSQL query using the instance's database connection details.
     * It uses the `getPsqlConfigs` function to get the configuration for the database and the tunnel,
     * and then calls the `runWithTunnel` function to execute the query.
     *
     * @param query - The SQL query to execute
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Promise that resolves to the query result as a string
     */
    execQuery(query: string, psqlCmdArgs?: string[]): Promise<string>;
    /**
     * Fetches the PostgreSQL version from the database by executing the `SHOW server_version` query.
     *
     * @returns Promise that resolves to the PostgreSQL version as a string (or undefined).
     */
    fetchVersion(): Promise<string | undefined>;
    /**
     * Executes a PostgreSQL interactive session using the instance's database connection details.
     * It uses the `getPsqlConfigs` function to get the configuration for the database and the tunnel,
     * and then calls the `runWithTunnel` function to execute the query.
     *
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Promise that resolves to the query result as a string
     */
    interactiveSession(psqlCmdArgs?: string[]): Promise<string>;
    /**
     * Runs the psql command with tunnel support.
     *
     * @param tunnelConfig - The tunnel configuration object
     * @param options - The options for spawning the psql process
     * @returns Promise that resolves to the query result as a string
     */
    runWithTunnel(tunnelConfig: TunnelConfig, options: Parameters<typeof this.spawnPsql>[0]): Promise<string>;
    /**
     * Consumes a stream and returns its content as a string.
     *
     * @param inputStream - The input stream to consume
     * @returns Promise that resolves to the stream content as a string
     */
    private consumeStream;
    /**
     * Kills a child process if it hasn't been killed already.
     * According to node.js docs, sending a kill to a process won't cause an error
     * but could have unintended consequences if the PID gets reassigned.
     * To be on the safe side, check if the process was already killed before sending the signal.
     *
     * @param childProcess - The child process to kill
     * @param signal - The signal to send to the process
     * @returns void
     */
    private kill;
    /**
     * Creates the options for spawning the psql process for a SQL file execution.
     *
     * @param file - The path to the SQL file to execute
     * @param dbEnv - The database environment variables
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Object containing child process options, database environment, and psql arguments
     */
    private psqlFileOptions;
    /**
     * Creates the options for spawning the psql process for an interactive psql session.
     *
     * @param prompt - The prompt to use for the interactive psql session
     * @param dbEnv - The database environment variables
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Object containing child process options, database environment, and psql arguments
     */
    private psqlInteractiveOptions;
    /**
     * Creates the options for spawning the psql process for a single query execution.
     *
     * @param query - The SQL query to execute
     * @param dbEnv - The database environment variables
     * @param psqlCmdArgs - Additional command-line arguments for psql (default: [])
     * @returns Object containing child process options, database environment, and psql arguments
     */
    private psqlQueryOptions;
    /**
     * Spawns the psql process with the given options.
     *
     * @param options - The options for spawning the psql process
     * @returns The spawned child process
     */
    private spawnPsql;
    /**
     * Traps SIGINT so that ctrl+c can be used by psql without killing the parent node process.
     * You can use ctrl+c in psql to kill running queries while keeping the psql process open.
     * This code is to stop the parent node process (heroku CLI) from exiting.
     * If the parent Heroku CLI node process exits, then psql will exit as it is a child process.
     *
     * @param childProcess - The child process to forward signals to
     * @returns Function to restore the original signal handlers
     */
    private trapAndForwardSignalsToChildProcess;
    /**
     * Waits for the psql process to exit and handles any errors.
     *
     * @param psql - The psql process event emitter
     * @throws Error if psql exits with non-zero code or if psql command is not found
     * @returns Promise that resolves to void when psql exits
     */
    private waitForPSQLExit;
}
