#!/usr/bin/env python3
"""Generate raw, comparable voice samples without cloud services."""

import argparse
import wave
from pathlib import Path


TEXT = (
    "Здесь звук приходит короткими пакетами. Но задержку ответа нельзя "
    "сводить к сети: распознавание, сценарий и модель надо измерять отдельно."
)


def piper(model_path: Path, output_path: Path) -> None:
    from piper import PiperVoice

    voice = PiperVoice.load(str(model_path))
    with wave.open(str(output_path), "wb") as wav_file:
        voice.synthesize_wav(TEXT, wav_file)


def silero(model_path: Path, speaker: str, output_path: Path) -> None:
    import numpy as np
    import torch

    model = torch.package.PackageImporter(str(model_path)).load_pickle(
        "tts_models", "model"
    )
    model.to(torch.device("cpu"))
    samples = model.apply_tts(
        text=TEXT,
        speaker=speaker,
        sample_rate=48000,
        put_accent=True,
        put_yo=True,
        put_stress_homo=True,
        put_yo_homo=True,
    )
    pcm = np.clip(np.asarray(samples), -1.0, 1.0)
    pcm = (pcm * 32767).astype("<i2")
    with wave.open(str(output_path), "wb") as wav_file:
        wav_file.setnchannels(1)
        wav_file.setsampwidth(2)
        wav_file.setframerate(48000)
        wav_file.writeframes(pcm.tobytes())


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("engine", choices=["piper", "silero"])
    parser.add_argument("--model", type=Path, required=True)
    parser.add_argument("--speaker", default="xenia")
    parser.add_argument("--output", type=Path, required=True)
    args = parser.parse_args()
    args.output.parent.mkdir(parents=True, exist_ok=True)
    if args.engine == "piper":
        piper(args.model, args.output)
    else:
        silero(args.model, args.speaker, args.output)


if __name__ == "__main__":
    main()
