// storage/license-store.ts — Persistence layer for license state (~/.planu/data/global/license.json).
import { readdir } from 'node:fs/promises';
import { join } from 'node:path';
import { readJson, writeJson, globalDataDir, safeJsonParse } from './base-store.js';
import { withFileLock } from './file-mutex.js';
// ---------------------------------------------------------------------------
// Paths
// ---------------------------------------------------------------------------
function licenseFile() {
    return join(globalDataDir(), 'license.json');
}
/**
 * Legacy path used before SPEC-537: data/global/license.json (cwd-relative).
 * We attempt a one-time migration from this path to the new absolute location.
 */
function legacyLicenseFile() {
    return join('data', 'global', 'license.json');
}
// ---------------------------------------------------------------------------
// Migration helper (runs once, silently)
// ---------------------------------------------------------------------------
async function migrateLegacyLicense() {
    const legacy = legacyLicenseFile();
    const current = licenseFile();
    // Skip if already at the same path (e.g. PLANU_GLOBAL_DATA_DIR override points to cwd)
    if (legacy === current) {
        return;
    }
    const { readFile, rename, mkdir } = await import('node:fs/promises');
    const { dirname } = await import('node:path');
    try {
        const raw = await readFile(legacy, 'utf-8');
        const legacyState = safeJsonParse(raw, {});
        // Only migrate a real license state (must have a licenseKey field)
        if (typeof legacyState.licenseKey !== 'string' || legacyState.licenseKey.length === 0) {
            return;
        }
        await mkdir(dirname(current), { recursive: true });
        await rename(legacy, current);
    }
    catch {
        // File does not exist or is not readable — nothing to migrate
    }
}
let migrationDone = false;
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
export async function getLicenseState() {
    if (!migrationDone) {
        migrationDone = true;
        await migrateLegacyLicense();
    }
    return readJson(licenseFile(), null);
}
export async function saveLicenseState(state) {
    await withFileLock(licenseFile(), async () => {
        await writeJson(licenseFile(), state);
    });
}
export async function deleteLicenseState() {
    const { unlink } = await import('node:fs/promises');
    try {
        await unlink(licenseFile());
    }
    catch (err) {
        if (isNodeError(err) && err.code === 'ENOENT') {
            return;
        }
        throw err;
    }
}
export async function countActiveProjects() {
    try {
        const entries = await readdir('data/projects', { withFileTypes: true });
        return entries.filter((e) => e.isDirectory()).length;
    }
    catch (err) {
        if (isNodeError(err) && err.code === 'ENOENT') {
            return 0;
        }
        throw err;
    }
}
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
function isNodeError(err) {
    return err instanceof Error && 'code' in err;
}
//# sourceMappingURL=license-store.js.map