import subprocess
import logging
import datetime
import os.path
import shlex
import time
import lib.connection as Connection
from gi.repository import GObject
import copy

# TODO: move templates to config file
ffmpegtemplate = """ffmpeg -y -nostdin \
{inputs} \
-ac 2 -aspect 16:9 \
{videotracks} \
{audiotracks} \
-flags +global_header -flags +ilme+ildct \
-f segment -segment_time 180 -segment_format mpegts {filename}-%d.ts"""
videotracktemplate = "-map {id}:v -c:v:{id} mpeg2video -pix_fmt:v:{id} yuv420p -qscale:v:{id} 2 -qmin:v:{id} 2 -qmax:v:{id} 7 -keyint_min 0 -bf:{id} 0 -g:{id} 0 -intra:{id} -maxrate:{id} 90M "
audiotracktemplate = "-map {id}:a -c:a:{id} mp2 -b:a:{id} 192k -ac:a:{id} 2 -ar:a:{id} 48000 "
inputtemplate = "-i tcp://{host}:{port} "
filenameTemplate = "voctorec_{year}-{month}-{day}_{hour}-{minute}-{second}"

class MultiTrackRec:
    def __init__(self):
        self.recording = False
        self.curTime = ""
        self.curBitrate = ""
        self.curSize = ""
        self.ffmpegProcess = None
        self.videotracks = list()
        self.audiotracks = list()
        self.segmented = True
        self.segment_time = 180
        self.log = logging.getLogger("multitrackrec")
        self.log.info("MultiTrackRecorder Initialized")
        self.basepath = "/home/zoadmin/record/"
        self.folderpath = None

    def add_video_track(self, port, id, name):
        track = {"id": int(id), "name": str(name), "port": int(port)}
        self.videotracks.append(track)
        self.log.info("Added Videotrack {name}".format(name=name))
        self.log.debug("Track: " + str(track))

    def add_audio_track(self, id, name):
        track = {"id": int(id), "name": str(name)}
        self.audiotracks.append(track)
        self.log.info("Added Audiotrack {name}".format(name=name))
        self.log.debug("Track: " + str(track))

    def start_recording(self):

        self.log.info('starting recording')

        date = datetime.datetime.now()

        foldername = filenameTemplate.format(year=date.year, month=date.month, day=date.day, hour=date.hour,
                                           minute=date.minute, second=date.second)
        foldernamecopy = copy.copy(foldername)
        self.log.debug(foldername)
        self.log.debug(self.basepath)
        i = 0
        folderpath = self.basepath + foldername
        while os.path.exists(folderpath):
            folderpath = self.basepath + foldernamecopy + "_" + str(i)
            i += 1

        self.log.info("Creating Folder " + folderpath)
        os.mkdir(folderpath)


        cmd = self.get_ffmpeg_str(folderpath + "/segment")
        parsed = shlex.split(cmd)
        self.log.debug("Parsed cmd: " + str(parsed))
        self.folderpath = folderpath

        if not self.ffmpegProcess:
            self.log.info("Starting FFmpeg Recording Process")
            self.ffmpegProcess = subprocess.Popen(parsed, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

        else:
            self.log.error("Error: Process already running / exited unexpectedly. Restarting instead.")
            self.ffmpegProcess.terminate()
            self.ffmpegProcess = None
            self.start_recording()
        self.recording = True
        Connection.send("message", "rec_running")
        GObject.io_add_watch(self.ffmpegProcess.stderr, GObject.IO_IN, self.on_data)

    def stop_recording(self):
        self.ffmpegProcess.terminate()
        self.ffmepgProcess = None
        self.recording = False
        Connection.send("message", "rec_stop")

    def on_data(self, source, _, *args):
        line = source.readline()
        line = line.split()
        self.log.debug(line)
        for l in line:
            if "time=" in l:
                self.curTime = l[5:]
        a = subprocess.run(['du', '-h', '-s', self.folderpath], stdout=subprocess.PIPE)
        b = subprocess.run(['df', '-h', '--output=avail', '/dev/sda1'], stdout=subprocess.PIPE)
        self.curSize = str(a.stdout.split()[0], encoding='utf-8').replace(',', '.')
        self.availSize = str(b.stdout.split()[1], encoding='utf-8')
        self.log.debug("Time: {}, Avail: {}, Size: {}".format(self.curTime, self.availSize, self.curSize))
        Connection.send("message", "recstatus,{},{},{}".format(self.curTime, self.availSize, self.curSize))
        return True

    def get_ffmpeg_str(self, name):
        audioStr = ""
        videoStr = ""
        inputStr = ""
        for track in self.videotracks:
            videoStr += videotracktemplate.format(id=track["id"])
            inputStr += inputtemplate.format(host="localhost", port=track["port"])
        for track in self.audiotracks:
            audioStr += audiotracktemplate.format(id=track["id"])
        date = datetime.date.today()
        time = datetime.time()

        ffstr = ffmpegtemplate.format(inputs=inputStr, videotracks=videoStr, audiotracks=audioStr, filename=name)
        self.log.debug("FFmpeg String generated: " + ffstr)
        return ffstr
