/**
 * SAC task polling
 */
import { requestJson } from "./client.js";
import { taskEndpoint } from "./endpoints.js";
import { SACError, ExitCode } from "./errors.js";
import { createSpinner } from "./output.js";
const NETWORK_RETRY_LIMIT = 3;
export async function pollTask(config, opts) {
    const intervalSec = opts.intervalSec ?? 3;
    const timeoutSec = opts.timeoutSec ?? config.timeout;
    const deadline = Date.now() + timeoutSec * 1000;
    const spinner = createSpinner("Waiting for task...");
    if (!config.quiet)
        spinner.start();
    let networkErrors = 0;
    try {
        while (Date.now() < deadline) {
            let data;
            try {
                data = await requestJson(config, {
                    url: taskEndpoint(config, opts.taskId),
                    method: "GET",
                }, opts.apiKey);
                networkErrors = 0; // reset on success
            }
            catch (err) {
                const isNetwork = err instanceof SACError && err.exitCode === ExitCode.NETWORK;
                if (isNetwork && networkErrors < NETWORK_RETRY_LIMIT) {
                    networkErrors++;
                    if (!config.quiet)
                        spinner.update(`Network error, retrying (${networkErrors}/${NETWORK_RETRY_LIMIT})...`);
                    await new Promise((r) => setTimeout(r, intervalSec * 1000));
                    continue;
                }
                // Network exhausted - attach task_id so the caller can surface it
                if (err instanceof SACError)
                    err.taskId = opts.taskId;
                throw err;
            }
            const status = data.status?.toLowerCase() ?? "";
            if (!config.quiet) {
                const pct = data.progress != null ? ` ${Math.round(data.progress * 100)}%` : "";
                spinner.update(`Status: ${status}${pct}`);
            }
            if (status === "completed") {
                spinner.stop("Done.");
                return data;
            }
            if (status === "failed") {
                spinner.stop("Failed.");
                const apiErr = data.error;
                const detail = apiErr?.error_message ?? (apiErr ? JSON.stringify(apiErr) : undefined);
                const msg = detail ? `Task failed: ${detail}` : "Task failed.";
                throw new SACError(msg, ExitCode.GENERAL);
            }
            await new Promise((r) => setTimeout(r, intervalSec * 1000));
        }
    }
    finally {
        spinner.stop();
    }
    const timeoutErr = new SACError("Task timed out.", ExitCode.TIMEOUT, `Task is still running. Resume with: seawork sac task ${opts.taskId} --wait`);
    timeoutErr.taskId = opts.taskId;
    throw timeoutErr;
}
//# sourceMappingURL=poll.js.map