import { IReactiveFileSystem, TypedEventEmitter, FileSystemEventPayloads, FileEntry, FileMetadata, FSEvent, Disposable, FileStat } from '@firesystem/core';

interface S3FileSystemConfig {
    /**
     * The S3 bucket name
     */
    bucket: string;
    /**
     * AWS region
     */
    region: string;
    /**
     * Optional prefix to namespace all operations
     * @default "/"
     */
    prefix?: string;
    /**
     * AWS credentials
     */
    credentials: {
        accessKeyId: string;
        secretAccessKey: string;
    };
    /**
     * Optional S3 client configuration
     */
    clientOptions?: {
        endpoint?: string;
        forcePathStyle?: boolean;
    };
    /**
     * Compatibility mode
     * - "strict": Requires directory markers and metadata (default for new systems)
     * - "lenient": Works with any existing S3 structure
     * @default "strict"
     */
    mode?: "strict" | "lenient";
}

declare class S3FileSystem implements IReactiveFileSystem {
    private client;
    private config;
    private watchers;
    readonly events: TypedEventEmitter<FileSystemEventPayloads>;
    constructor(config: S3FileSystemConfig);
    initialize(): Promise<void>;
    private toS3Key;
    private fromS3Key;
    private streamToString;
    private ensureDirectoryMarker;
    private ensureParentExists;
    private parseS3Metadata;
    private createS3Metadata;
    readFile(path: string): Promise<FileEntry>;
    writeFile(path: string, content: any, metadata?: FileMetadata): Promise<FileEntry>;
    deleteFile(path: string): Promise<void>;
    exists(path: string): Promise<boolean>;
    readDir(path: string): Promise<FileEntry[]>;
    mkdir(path: string, recursive?: boolean): Promise<FileEntry>;
    rmdir(path: string, recursive?: boolean): Promise<void>;
    rename(oldPath: string, newPath: string): Promise<FileEntry>;
    move(sourcePaths: string[], targetPath: string): Promise<void>;
    copy(sourcePath: string, targetPath: string): Promise<FileEntry>;
    watch(pattern: string, callback: (event: FSEvent) => void): Disposable;
    private notifyWatchers;
    private matchGlob;
    private isDirectory;
    stat(path: string): Promise<FileStat>;
    glob(pattern: string): Promise<string[]>;
    clear(): Promise<void>;
    size(): Promise<number>;
    canModify(path: string): Promise<boolean>;
    canCreateIn(parentPath: string): Promise<boolean>;
}

export { S3FileSystem, type S3FileSystemConfig };
