import json
import logging
import argparse
from io import BytesIO

from gtts import gTTS
from pydub import AudioSegment
from pydub.playback import play
from vosk import Model

from py_speech_service.grammar_parser import GrammarParser
from version import Version

import speech_recognition as sr

def cli():
    try:
        parser = argparse.ArgumentParser("py-speech-service",
                                         description="Commandline Python application for TTS and SST")
        parser.add_argument("-v", "--version", help="Get the version number", action='store_true')
        parser.add_argument("-g", "--grammar", help="The grammar file to use", type=str)
        parser.add_argument("-m", "--model", help="The VOSK model folder", type=str)
        args = parser.parse_args()

        if args.version:
            print("py-speech-service v" + Version.name())
            return

        if not args.grammar:
            print("usage: py-speech-service -g GrammarFilePath -m VoskModelPath")
            return

        if not args.model:
            print("usage: py-speech-service -g GrammarFilePath -m VoskModelPath")
            return

        previous_text = "init"
        grammar_parser = GrammarParser()
        grammar_parser.set_grammar_file(args.grammar)

        r = sr.Recognizer()
        r.vosk_model = Model(args.model)
        with sr.Microphone() as source:
            r.adjust_for_ambient_noise(source)
            r.pause_threshold = 1.2
            while True:
                try:
                    if previous_text != "":
                        print("Please state your command")
                    audio = r.listen(source)
                    text_recognized = r.recognize_vosk(audio)
                    if text_recognized is None:
                        previous_text = ""
                        continue
                    text_recognized = json.loads(text_recognized)['text']
                    if text_recognized == "":
                        previous_text = ""
                        continue
                    previous_text = text_recognized
                    print("I heard: '" + text_recognized + "'")
                    match = grammar_parser.find_match(text_recognized)
                    #match = grammar_parser.find_match("a tracker track content")
                    if match is not None:
                        reply = "I am " + str(round(match.confidence, 2)) + "% sure you said '" + match.matched_text + "'"
                        print(reply)
                        if match.confidence > 90:
                            identified_command = match.rule
                            if len(match.values) > 0:
                                identified_command += " | Values: "
                                for pair in match.values:
                                    identified_command += pair[0] + "=" + str(pair[1]) + ", "
                            print("Executed command: " + identified_command)
                            mp3_file_object = BytesIO()
                            tts = gTTS(text=reply, lang="en", slow=False)
                            tts.write_to_fp(mp3_file_object)
                            mp3_file_object.seek(0)
                            sound = AudioSegment.from_file(mp3_file_object, format="mp3")
                            so = sound.speedup(1.1)
                            play(so)
                    else:
                        print("I have no clue what you meant there")

                except sr.UnknownValueError:
                    print("Apologies, the audio wasn't clear enough.")
                except sr.RequestError as e:
                    print("There was an issue retrieving results. Error: {0}".format(e))


    except Exception as e:
        logging.error(e)


if __name__ == "__main__":
    cli()
