#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import asyncio
from functools import partial
import json
import logging
from pathlib import Path
import platform
import re
import tempfile
from typing import List
import uuid

from project_settings import project_path, log_directory, edge_tts_record_file, edge_tts_temp_directory
import log

log.setup(log_directory=log_directory)

import aiofiles
import anyio
import edge_tts
import gradio as gr

from toolbox.os.command import Command

main_logger = logging.getLogger("main")


def get_args():
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "--example_wav_dir",
        default=(project_path / "data/examples").as_posix(),
        type=str
    )
    args = parser.parse_args()
    return args


async def edge_tts_get_speakers() -> List[str]:
    edge_tts_speakers_choices = list()
    voices = await edge_tts.list_voices()
    for voice in voices:
        short_name = voice["ShortName"]
        edge_tts_speakers_choices.append(short_name)
    return edge_tts_speakers_choices


async def edge_tts_text_to_speech(text: str, speaker: str):
    communicate = edge_tts.Communicate(text, speaker)

    filename = edge_tts_temp_directory / "{}.wav".format(uuid.uuid4())
    async with aiofiles.open(edge_tts_record_file.as_posix(), "a+", encoding="utf-8") as f:
        await f.write(json.dumps({
            "text": text,
            "speaker": speaker,
            "filename": filename.as_posix(),
        }, ensure_ascii=False))

    await communicate.save(filename)
    return filename


def shell(cmd: str):
    return Command.popen(cmd)


def main():
    args = get_args()

    title = "## 电子书阅读."

    loop = asyncio.get_event_loop()
    edge_tts_speakers_choices = loop.run_until_complete(edge_tts_get_speakers())

    # blocks
    with gr.Blocks() as blocks:
        gr.Markdown(value=title)

        with gr.Tabs():
            with gr.TabItem("Ebook Reading"):
                e_book_reading_file = gr.File(
                    value=(project_path / "data/e_book/confucianism/the_analects.txt").as_posix(),
                    label="txt"
                )
                e_book_reading_tts_engine = gr.Dropdown(
                    choices=["Edge TTS"], value="Edge TTS", label="tts_engine"
                )
                e_book_reading_button = gr.Button(value="e_book_reading", variant="primary")
            with gr.TabItem("Edge TTS"):
                edge_tts_text = gr.Textbox(value="学而时习之,不亦悦乎。", lines=4, max_lines=50, label="text")
                edge_tts_speaker = gr.Dropdown(choices=edge_tts_speakers_choices, value="zh-CN-XiaoxiaoNeural", label="speakers")

                edge_tts_audio = gr.Audio(type="filepath", label="audio", autoplay=True)

                edge_tts_button = gr.Button(value="edge_tts", variant="primary")
            edge_tts_button.click(
                edge_tts_text_to_speech,
                inputs=[
                    edge_tts_text,
                    edge_tts_speaker,
                ],
                outputs=[
                    edge_tts_audio
                ],
            )
            with gr.TabItem("shell"):
                shell_text = gr.Textbox(label="cmd")
                shell_button = gr.Button("run")
                shell_output = gr.Textbox(label="output")

            shell_button.click(
                shell,
                inputs=[
                    shell_text,
                ],
                outputs=[
                    shell_output
                ],
            )

    launch = partial(
        blocks.queue().launch,
        share=False if platform.system() == "Windows" else False,
        server_name="127.0.0.1" if platform.system() == "Windows" else "0.0.0.0",
        server_port=7860,
    )
    anyio.run(
        launch,
        backend="asyncio"
    )
    return


if __name__ == "__main__":
    main()