import { randomUUID } from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import { getTokensFile } from "../config/index.js";
import { GoogleTokensSchema } from "../config/types.js";
export function parseGoogleTokensJson(tokensJson) {
    const parsed = JSON.parse(tokensJson);
    const tokens = GoogleTokensSchema.parse(parsed);
    if (!tokens.refresh_token.trim()) {
        throw new Error("Google OAuth tokens are missing refresh_token");
    }
    return tokens;
}
export function hasLocalGoogleRefreshToken() {
    const tokensFile = getTokensFile();
    if (!fs.existsSync(tokensFile))
        return false;
    try {
        const tokens = parseGoogleTokensJson(fs.readFileSync(tokensFile, "utf-8"));
        return tokens.refresh_token.trim() !== "";
    }
    catch {
        return false;
    }
}
export function writeGoogleTokensJson(tokensJson) {
    const serverTokens = parseGoogleTokensJson(tokensJson);
    const normalizedJson = `${JSON.stringify(serverTokens, null, 2)}\n`;
    const tokensFile = getTokensFile();
    const tmpFile = `${tokensFile}.tmp-${process.pid}-${Date.now()}-${randomUUID()}`;
    fs.mkdirSync(path.dirname(tokensFile), { recursive: true });
    let existingContent = null;
    if (fs.existsSync(tokensFile)) {
        try {
            existingContent = fs.readFileSync(tokensFile, "utf-8");
        }
        catch {
            existingContent = null;
        }
    }
    if (existingContent === normalizedJson) {
        return { tokensFile, changed: false };
    }
    if (existingContent !== null) {
        try {
            const localTokens = parseGoogleTokensJson(existingContent);
            // If the refresh token is unchanged, preserve the local file. Google
            // clients refresh access_token/expiry_date at runtime and save them
            // locally; the server copy may lag behind and should not clobber a
            // fresher local access token on the next startup heartbeat.
            if (localTokens.refresh_token === serverTokens.refresh_token) {
                return { tokensFile, changed: false };
            }
        }
        catch {
            // Invalid local tokens are replaced with the server copy below.
        }
    }
    fs.writeFileSync(tmpFile, normalizedJson, "utf-8");
    if (process.platform !== "win32") {
        try {
            fs.chmodSync(tmpFile, 0o600);
        }
        catch {
            // best-effort: POSIX permissions may be unsupported on some filesystems
        }
    }
    fs.renameSync(tmpFile, tokensFile);
    return { tokensFile, changed: true };
}
//# sourceMappingURL=token-file.js.map