import fs from 'fs';
import path from 'path';
import { execFileSync } from 'child_process';
export const DEFAULT_TTS_PROVIDER = 'edge';
export const DEFAULT_EDGE_TTS_VOICE = 'en-GB-SoniaNeural';
export const MAX_TTS_TEXT_LENGTH = 2000;
export const TTS_OUTBOUND_DIR = '/workspace/group/.nanoclaw-outbound/tts';
export function getTtsOutboundDir(env = process.env) {
    return env.NANOCLAW_TTS_OUTBOUND_DIR || TTS_OUTBOUND_DIR;
}
export function ensureTtsOutboundDir(env = process.env) {
    const dir = getTtsOutboundDir(env);
    fs.mkdirSync(dir, { recursive: true });
    return dir;
}
function createTtsOutputPath(extension = '.mp3', env = process.env) {
    const outboundDir = ensureTtsOutboundDir(env);
    const tempDir = fs.mkdtempSync(path.join(outboundDir, 'speech-'));
    return path.join(tempDir, `voice${extension}`);
}
export class EdgeTtsProvider {
    id = 'edge';
    mode = 'remote';
    synthesize(request, outputPath, env = process.env) {
        const edgeTtsBin = env.NANOCLAW_EDGE_TTS_BIN || 'edge-tts';
        const voice = request.voice || env.NANOCLAW_TTS_DEFAULT_VOICE || DEFAULT_EDGE_TTS_VOICE;
        execFileSync(edgeTtsBin, [
            '--text',
            request.text,
            '--voice',
            voice,
            '--write-media',
            outputPath,
        ], { stdio: 'pipe' });
        if (!fs.existsSync(outputPath) || fs.statSync(outputPath).size === 0) {
            throw new Error(`TTS provider ${this.id} produced no audio output`);
        }
        return {
            provider: this.id,
            mode: this.mode,
            filePath: outputPath,
            mediaType: 'audio/mpeg',
        };
    }
}
const providers = new Map([
    ['edge', new EdgeTtsProvider()],
]);
export function resolveTtsProvider(providerId, env = process.env) {
    const requested = (providerId || env.NANOCLAW_TTS_DEFAULT_PROVIDER || DEFAULT_TTS_PROVIDER).trim().toLowerCase();
    const provider = providers.get(requested);
    if (!provider) {
        throw new Error(`Unsupported TTS provider: ${requested}`);
    }
    return provider;
}
export function synthesizeSpeech(request, env = process.env) {
    const text = request.text.trim();
    if (!text) {
        throw new Error('TTS text must not be empty');
    }
    if (text.length > MAX_TTS_TEXT_LENGTH) {
        throw new Error(`TTS text exceeds ${MAX_TTS_TEXT_LENGTH} characters`);
    }
    const provider = resolveTtsProvider(request.provider, env);
    const outputPath = createTtsOutputPath('.mp3', env);
    try {
        return provider.synthesize({ ...request, text }, outputPath, env);
    }
    catch (err) {
        try {
            fs.rmSync(path.dirname(outputPath), { recursive: true, force: true });
        }
        catch {
            // Ignore cleanup failures after TTS errors.
        }
        throw err;
    }
}
//# sourceMappingURL=tts.js.map