import { gracefulExit } from './chunk-XQSWW35O.js';
import { define } from './chunk-WIL4LMMA.js';
import { loadVarlockEnvGraph, writeBackValue } from './chunk-5SI4EGRL.js';
import { CliExitError } from './chunk-7M6WZ65V.js';
import { FileBasedDataSource, ParsedEnvSpecFunctionCall, ParsedEnvSpecStaticValue, multiselect, ansis_default, password } from './chunk-LTYLEVHC.js';
import { q } from './chunk-7OJKCWSO.js';
import { encryptValue, getBackendInfo, ensureKey, getDaemonClient } from './chunk-JE2IMKMO.js';
import { __name } from './chunk-IBAHCH6O.js';
import path from 'path';
import fs from 'fs';

var commandSpec = define({
  name: "encrypt",
  description: "Encrypt a value using device-local encryption",
  args: {
    "key-id": {
      type: "string",
      description: "Encryption key ID (default: varlock-default)",
      default: "varlock-default"
    },
    file: {
      type: "string",
      description: "Path to a .env file \u2014 encrypts all sensitive plaintext values in-place"
    }
  }
});
async function encryptFile(keyId, filePath) {
  const resolvedPath = path.resolve(filePath);
  if (!fs.existsSync(resolvedPath)) {
    throw new CliExitError(`File not found: ${resolvedPath}`);
  }
  const envGraph = await loadVarlockEnvGraph();
  await envGraph.resolveEnvValues();
  const targetSource = envGraph.sortedDataSources.find(
    (s) => s instanceof FileBasedDataSource && s.fullPath === resolvedPath
  );
  if (!targetSource) {
    throw new CliExitError(
      `File "${filePath}" is not part of the loaded env graph`,
      { suggestion: "Make sure the file is in the project directory or imported by your schema." }
    );
  }
  const itemsToEncrypt = [];
  for (const [key, itemDef] of Object.entries(targetSource.configItemDefs)) {
    const graphItem = envGraph.configSchema[key];
    if (!graphItem?.isSensitive) continue;
    if (itemDef.parsedValue instanceof ParsedEnvSpecFunctionCall) continue;
    if (!(itemDef.parsedValue instanceof ParsedEnvSpecStaticValue)) continue;
    const val = itemDef.parsedValue.unescapedValue;
    if (val === void 0 || val === "" || typeof val !== "string") continue;
    itemsToEncrypt.push({ key, value: val });
  }
  if (itemsToEncrypt.length === 0) {
    console.log("No sensitive plaintext values found to encrypt.");
    return;
  }
  console.log("Only items marked as @sensitive in the schema are shown.");
  console.log("If a key is missing, add @sensitive to it in your schema file.\n");
  const selected = await multiselect({
    message: `Confirm values to encrypt in ${filePath} ${ansis_default.gray("(use arrows, space to toggle, enter to confirm)")}`,
    options: itemsToEncrypt.map((item) => ({
      value: item.key,
      label: item.key
    })),
    initialValues: itemsToEncrypt.map((item) => item.key)
  });
  if (q(selected)) return gracefulExit();
  const selectedKeys = new Set(selected);
  const filteredItems = itemsToEncrypt.filter((item) => selectedKeys.has(item.key));
  if (filteredItems.length === 0) {
    console.log("No items selected.");
    return;
  }
  console.log("");
  let encryptedCount = 0;
  for (const item of filteredItems) {
    const ciphertext = await encryptValue(item.value, keyId);
    const result = writeBackValue(item.key, `varlock("local:${ciphertext}")`, resolvedPath);
    if (result.updated) {
      encryptedCount++;
      console.log(`  Encrypted: ${item.key}`);
    }
  }
  console.log(`
Encrypted ${encryptedCount} value${encryptedCount !== 1 ? "s" : ""} in ${filePath}`);
}
__name(encryptFile, "encryptFile");
var commandFn = /* @__PURE__ */ __name(async (ctx) => {
  const keyId = String(ctx.values["key-id"] || "varlock-default");
  const backend = getBackendInfo();
  try {
    await ensureKey(keyId);
  } catch (err) {
    if (err instanceof CliExitError) throw err;
    throw new CliExitError(
      `Failed to check/create encryption key: ${err instanceof Error ? err.message : err}`
    );
  }
  console.log(`Using ${backend.type} backend (${backend.hardwareBacked ? "hardware-backed" : "file-based"})`);
  const filePath = ctx.values.file;
  if (filePath) {
    await encryptFile(keyId, filePath);
    return;
  }
  console.log("");
  let ciphertext;
  if (!process.stdin.isTTY) {
    const chunks = [];
    for await (const chunk of process.stdin) {
      chunks.push(chunk);
    }
    const rawValue = Buffer.concat(chunks).toString("utf-8").replace(/\r?\n$/, "");
    if (!rawValue) {
      throw new CliExitError("No value received on stdin");
    }
    try {
      ciphertext = await encryptValue(rawValue, keyId);
    } catch (err) {
      if (err instanceof CliExitError) throw err;
      throw new CliExitError(
        `Encryption failed: ${err instanceof Error ? err.message : err}`
      );
    }
  } else if (backend.biometricAvailable && backend.type === "secure-enclave") {
    const client = getDaemonClient();
    const result = await client.promptSecret({ keyId });
    if (!result) {
      return gracefulExit();
    }
    ciphertext = result;
  } else {
    const prompted = await password({ message: "Enter the value you want to encrypt", hint: "for multi-line values, pipe via stdin" });
    if (q(prompted)) return gracefulExit();
    try {
      ciphertext = await encryptValue(prompted, keyId);
    } catch (err) {
      if (err instanceof CliExitError) throw err;
      throw new CliExitError(
        `Encryption failed: ${err instanceof Error ? err.message : err}`
      );
    }
  }
  console.log("\nCopy this into your .env.local file and rename the key appropriately:\n");
  console.log(`SOME_SENSITIVE_KEY=varlock("local:${ciphertext}")`);
}, "commandFn");

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