import { define } from './chunk-WIL4LMMA.js';
import { formatDuration, formatTimeAgo } from './chunk-VT7SXRVK.js';
import { ansis_default, confirm, select } from './chunk-LTYLEVHC.js';
import { q } from './chunk-7OJKCWSO.js';
import { getCacheEnvKey, createEnvKeyCacheStore } from './chunk-223S32SW.js';
import { groupKeyPrefix, CacheStore } from './chunk-Y2ROUSC3.js';
import { keyExists } from './chunk-JE2IMKMO.js';
import { __name } from './chunk-IBAHCH6O.js';
import fs from 'fs';
import path from 'path';

var commandSpec = define({
  name: "cache",
  description: "Manage the varlock cache",
  args: {
    plugin: {
      type: "string",
      description: "Clear cache for a specific plugin only"
    },
    yes: {
      type: "boolean",
      short: "y",
      description: "Skip confirmation prompts (required for non-interactive `clear`)"
    }
  },
  examples: `
Manage the encrypted value cache used by cache() and plugin authors.

Examples:
  varlock cache                       # Interactive cache browser (or status summary if non-TTY)
  varlock cache status                # Print cache status summary (non-interactive)
  varlock cache clear --yes           # Clear all entries (no prompt)
  varlock cache clear --plugin 1password --yes  # Clear cache for a specific plugin
`.trim()
});
function formatResolverSourcePath(sourcePath) {
  const homeDir = process.env.HOME;
  if (homeDir && sourcePath.startsWith(`${homeDir}/`)) {
    return `~/${sourcePath.slice(homeDir.length + 1)}`;
  }
  const relToCwd = path.relative(process.cwd(), sourcePath);
  if (relToCwd && !relToCwd.startsWith("..") && !path.isAbsolute(relToCwd)) {
    return `./${relToCwd}`;
  }
  return sourcePath;
}
__name(formatResolverSourcePath, "formatResolverSourcePath");
function getGroupLabel(prefix) {
  if (prefix.startsWith("plugin:")) {
    return `${ansis_default.magenta(`[${prefix.replace("plugin:", "")}]`)} plugin cache`;
  }
  if (prefix === "resolver:custom") {
    return `${ansis_default.cyan("[resolver:custom]")} explicit keys`;
  }
  if (prefix.startsWith("resolver:")) {
    const sourcePath = prefix.slice("resolver:".length);
    return `${ansis_default.cyan("[resolver]")} ${ansis_default.gray(formatResolverSourcePath(sourcePath))}`;
  }
  return prefix;
}
__name(getGroupLabel, "getGroupLabel");
function formatEntryLabel(entry) {
  const ttlMs = entry.expiresAt - entry.cachedAt;
  const isForever = ttlMs > 50 * 365.25 * 864e5;
  const ttlStr = isForever ? "forever" : formatDuration(ttlMs);
  const agoStr = formatTimeAgo(entry.cachedAt);
  const parts = entry.key.split(":");
  let line1;
  const line2 = ansis_default.gray(`  ttl: ${ttlStr} \xB7 cached ${agoStr}`);
  if (parts[0] === "plugin") {
    const pluginName = parts[1];
    const rest = parts.slice(2).join(":");
    line1 = `${ansis_default.magenta(`[${pluginName}]`)} ${rest}`;
  } else if (parts[0] === "resolver" && parts[1] === "custom") {
    line1 = `${ansis_default.cyan("[custom]")} ${parts.slice(2).join(":")}`;
  } else if (parts[0] === "resolver") {
    const itemKey = parts[2];
    const resolverText = parts.slice(3).join(":");
    line1 = `${ansis_default.cyan(itemKey)} ${ansis_default.gray("=")} ${resolverText}`;
  } else {
    line1 = entry.key;
  }
  return `${line1}
     ${line2}`;
}
__name(formatEntryLabel, "formatEntryLabel");
function groupEntries(entries) {
  const groups = {};
  for (const entry of entries) {
    const prefix = groupKeyPrefix(entry.key);
    groups[prefix] ??= [];
    groups[prefix].push(entry);
  }
  return groups;
}
__name(groupEntries, "groupEntries");
function printStatus(store) {
  const stats = store.getStats();
  const filePath = store.getFilePath();
  const fileSize = fs.existsSync(filePath) ? fs.statSync(filePath).size : 0;
  const sizeStr = fileSize < 1024 ? `${fileSize} B` : `${(fileSize / 1024).toFixed(1)} KB`;
  console.log(`
  ${ansis_default.bold("Varlock cache")}`);
  console.log(`  Location:     ${ansis_default.gray(filePath)}`);
  console.log(`  File size:    ${sizeStr}`);
  console.log(`  Total entries: ${stats.total}${stats.expired ? ansis_default.gray(` (${stats.expired} expired)`) : ""}`);
  if (Object.keys(stats.byPrefix).length > 0) {
    console.log("  By group:");
    for (const [prefix, count] of Object.entries(stats.byPrefix)) {
      console.log(`    ${prefix.padEnd(30)} ${count}`);
    }
  }
  console.log("");
}
__name(printStatus, "printStatus");
var isInteractive = /* @__PURE__ */ __name(() => process.stdout.isTTY && process.stdin.isTTY, "isInteractive");
var commandFn = /* @__PURE__ */ __name(async (ctx) => {
  const positionals = (ctx.positionals ?? []).slice(ctx.commandPath?.length ?? 0);
  const action = positionals[0];
  const envKey = getCacheEnvKey();
  let store;
  if (envKey) {
    try {
      store = createEnvKeyCacheStore(envKey);
    } catch (err) {
      console.error(ansis_default.red(`_VARLOCK_CACHE_KEY is set but invalid: ${err instanceof Error ? err.message : err}`));
      process.exitCode = 1;
      return;
    }
  } else {
    if (!keyExists()) {
      console.log(ansis_default.gray("  No encryption key found \u2014 cache is not active."));
      return;
    }
    store = new CacheStore();
  }
  if (action === "status") {
    printStatus(store);
    return;
  }
  if (action === "clear") {
    const pluginName = ctx.values.plugin;
    const skipConfirm = ctx.values.yes;
    const target = pluginName ? `cache entries for plugin "${pluginName}"` : "cache entries";
    if (!skipConfirm) {
      if (!isInteractive()) {
        console.error(ansis_default.red(`Refusing to clear ${target} without confirmation.`));
        console.error("  Re-run with --yes to confirm, or run interactively.");
        process.exitCode = 1;
        return;
      }
      const confirmed = await confirm({
        message: `Clear all ${target}? This cannot be undone.`,
        initialValue: false
      });
      if (q(confirmed) || !confirmed) {
        console.log(ansis_default.gray("  Aborted."));
        return;
      }
    }
    try {
      const count = pluginName ? await store.clearByPrefix(`plugin:${pluginName}:`) : await store.clearAll();
      console.log(`  Cleared ${count} ${target}`);
    } catch (err) {
      console.error(ansis_default.red(`Failed to clear ${target}: ${err instanceof Error ? err.message : err}`));
      process.exitCode = 1;
    }
    return;
  }
  if (!isInteractive()) {
    printStatus(store);
    return;
  }
  while (true) {
    const entries = store.listEntries();
    if (entries.length === 0) {
      console.log(ansis_default.gray("\n  Cache is empty.\n"));
      return;
    }
    const groups = groupEntries(entries);
    const filePath = store.getFilePath();
    const fileSize = fs.existsSync(filePath) ? fs.statSync(filePath).size : 0;
    const sizeStr = fileSize < 1024 ? `${fileSize}B` : `${(fileSize / 1024).toFixed(1)}KB`;
    console.log(`
  ${ansis_default.bold(`${entries.length} cached entries`)} ${ansis_default.gray(`(${sizeStr})`)}`);
    const options = [];
    for (const [prefix, items] of Object.entries(groups)) {
      const label = getGroupLabel(prefix);
      options.push({
        value: `group:${prefix}`,
        label: `${label} ${ansis_default.gray(`(${items.length} entries)`)}`
      });
    }
    options.push({ value: "__clear_all__", label: ansis_default.red(`Clear all ${entries.length} entries`) });
    options.push({ value: "__exit__", label: ansis_default.gray("Exit") });
    const selected = await select({
      message: "Select a group to browse or an action:",
      options
    });
    if (q(selected) || selected === "__exit__") return;
    if (selected === "__clear_all__") {
      const confirmed = await confirm({
        message: `Clear all ${entries.length} cache entries?`,
        initialValue: false
      });
      if (q(confirmed) || !confirmed) continue;
      const count = await store.clearAll();
      console.log(`  Cleared ${count} entries`);
      return;
    }
    if (typeof selected === "string" && selected.startsWith("group:")) {
      const prefix = selected.replace("group:", "");
      const groupLabel = getGroupLabel(prefix);
      while (true) {
        const current = store.listEntries().filter((e) => groupKeyPrefix(e.key) === prefix);
        if (current.length === 0) {
          console.log(ansis_default.gray("  No entries remaining in this group."));
          break;
        }
        const entryOptions = [
          ...current.map((entry) => ({
            value: entry.key,
            label: formatEntryLabel(entry)
          })),
          { value: "__clear_group__", label: ansis_default.red(`Clear all ${current.length} entries`) },
          { value: "__back__", label: ansis_default.gray("\u2190 Back") }
        ];
        const entrySelected = await select({
          message: `${groupLabel} \u2014 ${current.length} entries:`,
          options: entryOptions
        });
        if (q(entrySelected) || entrySelected === "__back__") break;
        if (entrySelected === "__clear_group__") {
          const confirmed2 = await confirm({
            message: `Clear all ${current.length} entries in "${prefix}"?`,
            initialValue: false
          });
          if (q(confirmed2) || !confirmed2) continue;
          await store.clearByPrefix(`${prefix}:`);
          console.log(ansis_default.gray(`  Cleared ${current.length} entries`));
          break;
        }
        const confirmed = await confirm({
          message: `Delete "${entrySelected}"?`,
          initialValue: true
        });
        if (q(confirmed) || !confirmed) continue;
        await store.delete(entrySelected);
        console.log(ansis_default.gray("  Deleted"));
      }
    }
  }
}, "commandFn");

export { commandFn, commandSpec };
//# sourceMappingURL=chunk-BVTQWPPV.js.map
//# sourceMappingURL=chunk-BVTQWPPV.js.map