import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { execFileSync } from "node:child_process";
import { GmailEmailClient } from "../email/gmail-email.js";
import { getMemoriesDir } from "../config/index.js";
import { logger } from "../logger.js";
/**
 * Generate a cryptographically secure random password.
 * Returns a 24-character alphanumeric string.
 */
function generatePassword() {
    return crypto.randomBytes(18).toString("base64url").slice(0, 24);
}
/**
 * Create a password-protected ZIP of identity.md.
 *
 * @returns Path to the created ZIP file (in a temp directory).
 */
function createEncryptedIdentityZip(identityPath, password) {
    const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "visionclaw-identity-"));
    const zipFile = path.join(tmpDir, "identity.zip");
    execFileSync("zip", ["-j", "-P", password, zipFile, identityPath], {
        stdio: "pipe",
    });
    return zipFile;
}
/**
 * Extract the ETH wallet address from identity.md content.
 */
function extractWalletAddress(content) {
    const match = /- Address:\s*(0x[0-9a-fA-F]+)/.exec(content);
    return match?.[1] ?? null;
}
/**
 * Send identity credentials to the owner using two-channel delivery:
 * 1. Email: encrypted ZIP of identity.md (contains all agent credentials)
 * 2. Telegram: decryption password
 *
 * This ensures no single channel compromise exposes sensitive credentials.
 */
export async function sendIdentityCredentials(config, ownerConfig, channelManager) {
    const identityPath = path.join(getMemoriesDir(), "identity.md");
    if (!fs.existsSync(identityPath)) {
        logger.warn("No identity.md found — skipping two-channel delivery");
        return;
    }
    const identityContent = fs.readFileSync(identityPath, "utf-8");
    const walletAddress = extractWalletAddress(identityContent);
    const password = generatePassword();
    let zipFile;
    try {
        zipFile = createEncryptedIdentityZip(identityPath, password);
        // Channel 1: Send encrypted file via email
        const addressLine = walletAddress
            ? `\nETH wallet address: ${walletAddress}\n`
            : "";
        const emailBody = `Hi ${ownerConfig.ownerName || "there"},

I'm sending you the credentials for my ETH wallet.
${addressLine}
For your reference, the agent's identity file is attached as an encrypted archive (identity.zip).
The decryption password has been sent to your Telegram account.

Note: The agent retains these credentials for operations. This copy is for your records.
- Open the encrypted file using the password from Telegram
- Save the credentials in a secure location (e.g., password manager) if you wish
- Never share private keys or recovery words with anyone

— ${config.agentName}`;
        const emailClient = new GmailEmailClient(config);
        await emailClient.sendEmail({
            to: ownerConfig.ownerEmail,
            subject: `${config.agentName} — Your Agent Credentials`,
            body: emailBody,
            attachments: [
                {
                    type: "file",
                    localPath: zipFile,
                    filename: "identity.zip",
                    mimeType: "application/zip",
                },
            ],
        });
        logger.system(`Identity credentials email sent to ${ownerConfig.ownerEmail}`);
        // Channel 2: Send decryption password via Telegram
        if (ownerConfig.telegramChatId) {
            const telegramMessage = `Your VisionClaw instance has it's own ETH wallet address: ${walletAddress}

The credentials for the wallet is sent to your email for your reference(the agent retains them for operations).
The decryption password for the email attachment is:
${password}
`;
            await channelManager.sendMessage("telegram", String(ownerConfig.telegramChatId), telegramMessage);
            logger.system("Credential decryption password sent via Telegram");
        }
        else {
            logger.warn("No Telegram chat ID — could not send decryption password. " +
                "Credential delivery incomplete!");
        }
    }
    finally {
        if (zipFile && fs.existsSync(zipFile)) {
            const tmpDir = path.dirname(zipFile);
            fs.rmSync(tmpDir, { recursive: true, force: true });
        }
    }
}
//# sourceMappingURL=send-identity-credentials.js.map