import { Integer } from '@epdoc/typeutil';
import * as fx from 'fs-extra';
import { FSBytes } from './fsbytes';
import { FSStats } from './fsstats';
import { FileConflictStrategy, FileName, FilePath, FolderName, FolderPath, FsDeepCopyOpts, FSSortOpts, GetChildrenOpts, SafeCopyOpts } from './types';
/**
 * Create a new FSItem object.
 * @param {(FSItem | FolderPath | FilePath)[])} args - An FSItem, a path, or a spread of paths to be used with path.resolve
 * @returns {FSItem} - A new FSItem object
 */
export declare function fsitem(...args: (FSItem | FolderPath | FilePath)[]): FSItem;
/**
 * An object representing a file system entry, which may be either a file or a
 * folder.
 *
 * Has methods to:
 *  - Retrieve properties of an existing file or folder.
 *  - Manipulate file paths.
 *  - Recursive support for reading the contents of folders
 *  - Safe copy and backup methods for an existing file or folder
 *  - Reading and writing files
 *  - Getting the creation dates of files, including using the metadata of some file formats
 *  - Testing files for equality
 */
export declare class FSItem {
    protected _isFSItem: boolean;
    protected _f: FilePath | FolderPath;
    protected _stats: FSStats;
    protected _haveReadFolderContents: boolean;
    protected _folders: FSItem[];
    protected _files: FSItem[];
    protected _args: (FilePath | FolderPath)[];
    /**
     * Create a new FSItem object from an existing FSItem object, a file path or
     * an array of file path parts that can be merged using node:path#resolve.
     * @param {(FSItem | FolderPath | FilePath)[])} args - An FSItem, a path, or a spread of paths to be used with path.resolve
     */
    constructor(...args: (FSItem | FolderPath | FilePath)[]);
    /**
     * Return a copy of this object. Does not copy the file.
     * @see FSItem#copyTo
     */
    copy(): FSItem;
    /**
     * Test if val is an FSItem object. Can be used as a typescript type gate.
     * @param val Any object
     * @returns
     */
    static isInstance(val: any): val is FSItem;
    /**
     * Append a file or folder name to this.f.
     * @param args A file name or array of file names.
     * @returns This
     */
    add(...args: FilePath[] | FolderPath[]): this;
    /**
     * Set the path to the home dir
     */
    home(...args: FilePath[] | FolderPath[]): this;
    get path(): FilePath;
    /**
     * Return the original parts that were used to make this.f. The value may
     * become out of sync with the actual value of this.f if too many operations
     * were performed on the path.
     * Use with caution. This may be deprecated.
     */
    get parts(): string[];
    /**
     * Returns the file's base file name, minus it's extension. For example, for
     * '/path/to/file.name.html', this method will return 'file.name'. Unlike
     * node:path
     * [basename](https://nodejs.org/api/path.html#pathbasenamepath-suffix)
     * method, this does NOT include the extension.
     * @return {string} The base portion of the filename, which excludes the file's extension.
     */
    get basename(): string;
    /**
     * Returns '/path/to' portion of /path/to/file.name.html'
     */
    get dirname(): string;
    /**
     * Returns the file extension, exluding the decimal character. For example,
     * '/path/to/file.name.html' will return 'html'.
     * @return {string} File extension, exluding the decimal character.
     */
    get extname(): string;
    /**
     * Returns the full filename of the file or folder, including it's extension.
     * For example, '/path/to/file.name.html' would return 'file.name.html'.
     * @return {string} - The full file or folder name, including it's extension, if any.
     */
    get filename(): string;
    /**
     * For folders, indicates if we have read the folder's contents.
     * @returns {boolean} - true if this is a folder and we have read the folder's contents.
     */
    haveReadFolderContents(): boolean;
    /**
     * Get the list of FSItem files that matched a previous call to getFiles() or
     * getChildren().
     * @returns {FSItem[]} Array of FSItem objects representing files.
     */
    get files(): FSItem[];
    /**
     * Get the list of filenames that matched a previous call to getFolders() or
     * getChildren().
     * @returns {FileName[]} Array of filenames.
     */
    get filenames(): FileName[];
    /**
     * Get the list of FSItem folders that matched a previous call to getFolders() or
     * getChildren().
     * @returns {FSItem[]} Array of FSItem objects representing folders.
     */
    get folders(): FSItem[];
    /**
     * Get the list of folder names that matched a previous call to getFolders() or
     * getChildren().
     * @returns {FolderName[]} Array of folder names.
     */
    get folderNames(): FolderName[];
    /**
     * Looks at the extension of the filename to determine if it is one of the
     * listed types.
     * @param type List of types (eg. 'jpg', 'png')
     * @returns
     */
    isType(...type: (RegExp | string)[]): boolean;
    /**
     * Tests the extension to see if this is a PDF file.
     * @param {boolean} [testContents=false] If true, tests the file contents as well (not implemented).
     * @returns {boolean} True if the extension indicates this is a PDF file.
     */
    isPdf(testContents?: boolean): boolean;
    /**
     * Tests the extension to see if this is an XML file.
     * @returns  {boolean} True if the extension indicates this is an XML file.
     */
    isXml(): boolean;
    /**
     * Tests the extension to see if this is a text file.
     * @returns {boolean} True if the extension indicates this is a text file.
     */
    isTxt(): boolean;
    /**
     * Tests the extension to see if this is a JSON file.
     * @returns {boolean} True if the extension indicates this is a JSON file.
     */
    isJson(): boolean;
    /**
   * Asynchronously reads a specified number of bytes from the file and returns
   * them as an FSBytes instance. In order to determine what type of file this is,
   * at least 24 bytes must be read.
  
   * @param {number} [length=24] The number of bytes to read from the file.
   * Defaults to 24.
   * @returns {Promise<FSBytes>} A promise that resolves with an FSBytes instance
   * containing the read bytes, or rejects with an error.
   */
    getBytes(length?: number): Promise<FSBytes>;
    /**
     * Set or change the extension of this file. `This` must be a file.
     * @param {string} ext The extension. The string may or may not include a leading '.'.
     * @returns {this} The current FSItem instance.
     */
    setExt(ext: string): this;
    /**
     * Set or change the basename of this file. `This` must be a file.
     * @param {string} val The new basename for the file.
     * @returns {this} The current FSItem instance.
     */
    setBasename(val: string): this;
    /**
     * Return the FSSTATS for this file, retrieving the stats and referencing them
     * with this._stats if they have not been previously read. FSSTATS can become
     * stale and should be reread if a file is manipulated.
     *
     * Example `fsutil('mypath/file.txt').getStats().isFile()`.
     *
     * @param {boolean} force Force retrieval of the states, even if they have
     * already been retrieved.
     * @returns {Promise<FSStats>} A promise with an FSStats object
     */
    getStats(force?: boolean): Promise<FSStats>;
    /**
     * Getter returns the FSStats object associated with this file. A previous
     * call to getStats() is needed in order to read stats from disk.
     * @return {FSStats} - The FSStats for this file, if they have been read.
     */
    get stats(): FSStats;
    /**
     * Is this a folder? Will retrieve the FSStats for the file system entry if
     * they haven't been previously read.
     * @returns a promise with value true if this is a folder.
     */
    isDirectory(): Promise<boolean>;
    /**
     * Calls the FSItem#isDirectory method.
     * @returns {Prommise<boolean>}
     * @see FSItem#isDirectory
     */
    isDir(): Promise<boolean>;
    /**
     * Calls the FSItem#isDirectory method.
     * @returns {Prommise<boolean>}
     * @see FSItem#isDirectory
     */
    isFolder(): Promise<boolean>;
    /**
     * Is this a file? Will retrieve the FSStats for the file system entry if they
     * haven't been previously read.
     * @returns a promise with value true if this is a file.
     */
    isFile(): Promise<boolean>;
    /**
     * Does this file or folder exist? Will retrieve the FSStats for the file
     * system entry if they haven't been previously read.
     * @returns a promise with value true if this exists.
     */
    exists(): Promise<boolean>;
    /**
     * Is this a folder? Will retrieve the FSStats for the file system entry if
     * they haven't been previously read.
     * @returns a promise with value true if this is a folder.
     * @deprecated Use isDir() method instead.
     */
    dirExists(): Promise<boolean>;
    /**
     * Is this a file? Will retrieve the FSStats for the file system entry if they
     * haven't been previously read.
     * @returns a promise with value true if this is a file.
     * @deprecated Use isFile() method instead.
     */
    fileExists(): Promise<boolean>;
    /**
     * When was this file system entry created? Will retrieve the FSStats for the
     * file system entry if they haven't been previously read.
     * @returns a promise with the Date this file was created.
     * @deprecated Use isFile() method instead.
     */
    createdAt(): Promise<Date | undefined>;
    /**
     * Test for equality with the basename of this file.
     * @param {string} name
     * @returns {boolean} True if equal
     */
    isNamed(name: string): boolean;
    /**
     * Ensures there is a folder with this path.
     * @param {fx.EnsureDirOptions | number} [options] Options for ensuring the directory.
     * @returns {Promise<unknown>} A promise that resolves when the directory is ensured.
     */
    ensureDir(options?: fx.EnsureDirOptions | number): Promise<unknown>;
    /**
     * Synchronous version of `ensureDir`.
     * @param {fx.EnsureDirOptions | number} [options] Options for ensuring the directory.
     * @returns {this} The current FSItem instance.
     */
    ensureDirSync(options?: fx.EnsureDirOptions | number): this;
    /**
     * Removes this file or folder.
     * @returns {Promise<void>} A promise that resolves when the file or folder is removed.
     */
    remove(): Promise<void>;
    /**
     * Copy this file or folder to the location `dest`.
     * @param dest
     * @param options An fx.CopyOptions object
     * @returns
     */
    copyTo(dest: FilePath | FSItem, options?: fx.CopyOptions): Promise<void>;
    /**
     * Syncronous version of `copyTo` method.
     * @param dest
     * @param options An fx.CopyOptionsSync object
     * @returns
     */
    copySync(dest: FilePath | FSItem, options?: fx.CopyOptionsSync): this;
    /**
     * Move `this` file or folder to the location `dest`.
     * @param {FilePath | FSItem} dest - The new path for the file
     * @param {fx.MoveOptions} options - Options to `overwrite` and `dereference` symlinks.
     * @returns {Promise<void>}
     */
    moveTo(dest: FilePath | FSItem, options?: fx.MoveOptions): Promise<void>;
    /**
     * If this is a folder, retrieves the list of matching files in this folder.
     * Repopulates this._files and this._folders in the process. Returns just the
     * filenames, not the full path.
     * @param regex (optional) Use to constrain results
     * @return Array of files within the folder
     */
    getFiles(regex?: RegExp): Promise<FSItem[]>;
    /**
     * If this is a folder, retrieves the list of matching folders in this folder.
     * Repopulates this._files and this._folders in the process. Returns just the
     * folder names, not the full path.
     * @param regex (optional) Use to constrain results
     * @return Array of folders with the folder
     */
    getFolders(regex?: RegExp): Promise<FSItem[]>;
    /**
     * If this is a folder, retrieves the list of matching files and folders in
     * this folder and stores the lists as this._files and this._folders.
     * @param opts.match (Optional) File or folder names must match this string or
     * RegExp. If not specified then file and folder names are not filtered.
     * @return {Promise<FSItem[]> - Array of all files and folders within this folder
     */
    getChildren(options?: Partial<GetChildrenOpts>): Promise<FSItem[]>;
    /**
     * Sorts the children (files and folders) of this FSItem.
     * @param {FSSortOpts} [opts={}] - Sorting options.
     * @returns {void}
     */
    sortChildren(opts?: FSSortOpts): void;
    /**
     * Sorts the folders of this FSItem alphabetically. Run getChildren() first.
     * @returns {this} The current FSItem instance.
     */
    sortFolders(): this;
    /**
     * Sorts the files of this FSItem alphabetically.
     * @returns {this} The current FSItem instance.
     */
    sortFiles(): this;
    /**
     * Sorts the files of this FSItem by size. Run getChildren() first.
     * @returns {this} The current FSItem instance.
     */
    sortFilesBySize(): this;
    /**
     * For files, calculate the checksum of this file
     * @returns {Promise<string>} A promise that resolves with the checksum of the file.
     */
    checksum(): Promise<unknown>;
    /**
     * For PDF files, gets the Creation Date of this file file by reading it's
     * metadata.
     * @returns {Promise<Date | undefined>} A promise that resolves with the creation date of the PDF file, or undefined if not found.
     */
    getPdfDate(): Promise<Date | undefined>;
    /**
     * Use checksums to test if this file is equal to path2
     * @param path2
     * @returns {Promise<boolean>} A promise that resolves with true if the files are equal, false otherwise.
     */
    filesEqual(path2: FilePath): Promise<boolean>;
    /**
     * Asynchronously reads a specified number of bytes from a file.
     *
     * @param {number} length The number of bytes to read from the file.
     * @param {Buffer} [buffer] An optional buffer to store the read bytes. If not provided, a new buffer will be allocated with the specified length.
     * @param {number} [offset=0] The offset within the buffer where to start storing the read bytes. Defaults to 0.
     * @param {number} [position=0] The offset within the file from where to start reading (optional). Defaults to 0.
     * @returns {Promise<Buffer>} A promise that resolves with the buffer containing the read bytes, or rejects with an error.
     * @throws {Error} Rejects the promise with any error encountered during the file opening, reading, or closing operations.
     */
    readBytes(length: Integer, buffer?: Buffer, offset?: Integer, position?: Integer): Promise<any>;
    /**
     * Reads the entire file as a buffer.
     * @returns {Promise<Buffer>} A promise that resolves with the file contents as a buffer.
     */
    readAsBuffer(): Promise<Buffer>;
    /**
     * Reads the entire file as a string.
     * @returns {Promise<string>} A promise that resolves with the file contents as a string.
     */
    readAsString(): Promise<any>;
    /**
     * Reads the file as JSON and parses it.
     * @returns {Promise<any>} A promise that resolves with the parsed JSON content.
     */
    readJson(): Promise<any>;
    /**
     * Reads the file as JSON, parses it, and performs a deep copy with optional transformations.
     * @param {FsDeepCopyOpts} [opts={}] - Options for the deep copy operation.
     * @returns {Promise<any>} A promise that resolves with the deeply copied and transformed JSON content.
     */
    deepReadJson(opts?: FsDeepCopyOpts): Promise<any>;
    /**
     * Performs a deep copy of the given data with optional transformations.
     * @param {any} a - The data to deep copy.
     * @param {FsDeepCopyOpts} [options] - Options for the deep copy operation.
     * @returns {Promise<any>} A promise that resolves with the deeply copied and transformed data.
     */
    private deepCopy;
    /**
     * Writes JSON data to the file.
     * @param {any} data - The data to write as JSON.
     * @returns {Promise<void>} A promise that resolves when the write operation is complete.
     */
    writeJson(data: any): Promise<void>;
    /**
     * Writes base64-encoded data to the file.
     * @param {string} data - The base64-encoded data to write.
     * @returns {Promise<void>} A promise that resolves when the write operation is complete.
     */
    writeBase64(data: string): Promise<void>;
    /**
     * Writes data to the file with the specified encoding.
     * @param {string | string[]} data - The data to write.
     * @param {BufferEncoding} [type='utf8'] - The encoding to use.
     * @returns {Promise<void>} A promise that resolves when the write operation is complete.
     */
    write(data: string | string[], type?: BufferEncoding): Promise<void>;
    /**
     * 'Backup' a file by moving it to a new filename. Use when copying a file to
     * the same location or creating a new file at the same location.
     * @param {BackupOpts} opts
     * @returns {Promise<FilePath | boolean>} - Path to file if file was backed
     * up, or true if the file didn't exist
     */
    backup(opts?: FileConflictStrategy): Promise<FilePath | boolean>;
    /**
     * Finds the next available indexed filename. For example, for `filename.ext`,
     * tries `filename-01.ext`, `filename-02.ext`, etc until it finds a filename
     * that is not used.
     * @param {Integer} [limit=32] - The maximum number of attempts to find an available filename.
     * @param {string} [sep='-'] - The separator to use between the filename and the index.
     * @returns {Promise<FilePath | undefined>} A promise that resolves with an available file path, or undefined if not found.
     */
    findAvailableIndexFilename(limit?: Integer, sep?: string): Promise<FilePath | undefined>;
    /**
     * Copy an existing file or directory to a new location. Optionally creates a
     * backup if there is an existing file or directory at `destFile`.
     * @param {FilePath | FSItem} destFile - The destination file or directory.
     * @param {SafeCopyOpts} [opts={}] - Options for the copy or move operation.
     * @returns {Promise<boolean | undefined>} A promise that resolves with true if the file was copied or moved, false otherwise.
     */
    safeCopy(destFile: FilePath | FSItem, opts?: SafeCopyOpts): Promise<boolean | undefined>;
    /**
     * Creates a new Error with the specified code and message, including the file path.
     * @param {any} code - The error code or Error object.
     * @param {string} [message] - The error message.
     * @returns {Error} A new Error object.
     */
    newError(code: any, message?: string): Error;
}
