/**
 * Persistent status line spinner.
 *
 * Shows an animated spinner on the last line of the terminal.
 * Regular output scrolls above it. Intercepts both stdout and stderr
 * writes to clear and redraw the spinner around each write.
 */
import chalk from 'chalk';
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
class StatusLineImpl {
    active = false;
    message = '';
    frame = 0;
    intervalId;
    rawStdoutWrite;
    savedStdoutWrite;
    savedStderrWrite;
    rendering = false;
    start(message) {
        if (this.active) {
            this.message = message;
            return;
        }
        if (!process.stdout.isTTY)
            return;
        this.active = true;
        this.message = message;
        this.frame = 0;
        this.savedStdoutWrite = process.stdout.write;
        this.savedStderrWrite = process.stderr.write;
        this.rawStdoutWrite = process.stdout.write.bind(process.stdout);
        const rawStderrWrite = process.stderr.write.bind(process.stderr);
        const raw = this.rawStdoutWrite;
        const wrapWrite = (origRaw) => (chunk) => {
            if (this.rendering)
                return origRaw(String(chunk));
            raw('\r\x1b[K');
            const result = origRaw(String(chunk));
            if (String(chunk).includes('\n'))
                this.render();
            return result;
        };
        process.stdout.write = wrapWrite(raw);
        process.stderr.write = wrapWrite(rawStderrWrite);
        this.intervalId = setInterval(() => this.render(), 80);
    }
    update(message) {
        this.message = message;
    }
    stop() {
        if (!this.active)
            return;
        this.active = false;
        if (this.intervalId) {
            clearInterval(this.intervalId);
            this.intervalId = undefined;
        }
        if (this.rawStdoutWrite) {
            this.rawStdoutWrite('\r\x1b[K');
        }
        if (this.savedStdoutWrite) {
            process.stdout.write = this.savedStdoutWrite;
            this.savedStdoutWrite = undefined;
        }
        if (this.savedStderrWrite) {
            process.stderr.write = this.savedStderrWrite;
            this.savedStderrWrite = undefined;
        }
        this.rawStdoutWrite = undefined;
    }
    render() {
        if (!this.rawStdoutWrite || !this.active)
            return;
        this.rendering = true;
        const f = FRAMES[this.frame++ % FRAMES.length];
        this.rawStdoutWrite(`\r${chalk.cyan(f)} ${this.message}`);
        this.rendering = false;
    }
}
export const statusLine = new StatusLineImpl();
//# sourceMappingURL=StatusLine.js.map