#!/usr/bin/python3
# -*- coding: utf-8 -*-

import os
import sys
import json
import subprocess
import traceback
import time
from datetime import datetime
import shutil
import random
import glob
import requests
from PIL import Image
import math, operator
from threading import Timer
from functools import reduce



def get_image(img_src, outimage, timeout=20 ):
    try:
        #timer = Timer(timeout+2, pipe.kill)
        print("src:::: " + img_src )
        r = requests.get(img_src, allow_redirects=True, timeout=5)
        print("image erantzuna::: " + str(r.status_code))
        if r.status_code < 200 or r.status_code > 300 :
            return False
        open(outimage, 'wb').write(r.content)
        return True
    except Exception as e:
        print("get image  exception  %s" % (str(e)))
        error=traceback.format_exc()
        print(error)
        return False

def create_slide( folder, outimage, length, duration ):
    print("create interval..........folder: " + folder )
    print("create outimage..........outimage: " + outimage )
    print( "PWD:::: "+ os.getcwd()  )
    non=os.getcwd()
    try:
        z=math.ceil(int(data['conf']['capture_timeout'])/length/duration)
        lst_files1 = glob.glob( os.path.normpath( folder + "/*.jpg") )
        lst_files1.sort(key=os.path.getmtime,reverse=True)
        lst_files=lst_files1[0:length]
        lst_files.sort()

        t=data['conf']['capture_timeout']
        concat_str_l=[]
        for b in range(z):
            for img in lst_files:
                concat_str_l.append("file '" + non +'/'+ img+"'")
                if t-1 <= duration:
                    concat_str_l.append("duration " + str(t-1) )
                    concat_str_l.append("file '" + non +'/'+ img+"'")
                    break
                else:
                    concat_str_l.append("duration " + str(duration) )
                t -=duration
        with open("/tmp/cinput.txt", "w") as text_file:
            text_file.write("\n".join(concat_str_l))

    except Exception as e:
        print("ffprobe  exception  %s" % (str(e)))
        error=traceback.format_exc()
        print(error)
        return False
    

    print( "PWD:::: "+ os.getcwd()  )

    cmd = [ "/usr/bin/ionice", "-c3", "ffmpeg","-y", "-f","concat","-safe","0","-i", "/tmp/cinput.txt","-vsync","vfr","-pix_fmt","yuv420p","-filter_complex", "scale='1024:-1'" , "-vcodec","h264", "-b:v","1024k", "-an", "-movflags","+faststart","-t", str(data['conf']['capture_timeout']), outimage]
    
    print("CMD: " + " ".join(cmd) )
    try:
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
        #timer = Timer(timeout+2, pipe.kill)
        #try:
        #timer.start()
        o2, e2 = pipe.communicate()
        #finally:
            #timer.cancel()
        #    print("---bukatu da----")

        #o2, e2 = pipe.communicate()
        returncode = pipe.returncode
        print("returncode::  " + str(returncode) )
        
        if returncode != 0:
            print("NO VALID SLIDER: " + folder + " -> " + outimage )
            if os.path.isfile(outimage):
                os.remove(outimage)
            return (pipe.returncode,e2)
                
        return True

    except Exception as e:
        print("ffprobe  exception  %s" % (str(e)))
        error=traceback.format_exc()
        print(error)
        return False



def get_video(invideo, outimage, t, timeout):
    print("\n\n\n---------qqq---------------\n\n\n")
    cmd = [ "/usr/bin/ionice", "-c3", "ffmpeg","-y", "-ss", str(t), "-i", invideo, "-filter_complex", "scale=1024:-1" , "-vcodec","h264", "-pix_fmt", "yuv420p", "-b:v","1024k", "-an", "-movflags","+faststart", "-t", str(timeout), outimage]
    print("CMD::: " + " ".join(cmd) )
    try:
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
        timer = Timer(timeout*2, pipe.kill)
        try:
            timer.start()
            o2, e2 = pipe.communicate()
        finally:
            timer.cancel()

        #o2, e2 = pipe.communicate()
        returncode = pipe.returncode
        print("returncode::  " + str(returncode) )
        
        
        
        if returncode != 0:
            print("NO VALID VIDEO: " + invideo + " -> " + outimage )
            print( str(o2))
            print( str(e2))
            if os.path.isfile(outimage):
                os.remove(outimage)

            return False
                
        return True

    except Exception as e:
        print("ffprobe  exception  %s" % (str(e)))
        error=traceback.format_exc()
        print(error)
        return False

def is_image_dark(image1, dark_num_color , dark_limit ):
    h1 = Image.open(image1).convert('L').histogram()
    
    dark = sum(h1[0:dark_num_color]) / 1.00 / sum(h1)
    print("DARK h1 sum:  " + str(sum(h1))  + "   limit dark: " + str(sum(h1[0:30])) + "  result: " + str( dark ) )

    if dark  > dark_limit:
        return True
    else:
        return False

def is_same_image( image1, image2):
        h1 = Image.open(image1).histogram()
        h2 = Image.open(image2).histogram()
        
        rms = math.sqrt(reduce(operator.add, map(lambda a, b: (a - b) ** 2, h1, h2)) / len(h1))
        if rms == 0:
            print("* SAME IMAGE!!!")
            return True
        return False

def get_video_webcam(hondartza):
    folder=data['conf']['path']+"/" +hondartza['izena']
    if not os.path.exists(folder):
        os.makedirs(folder,mode=0o777)

    new_name=str(int(time.time())) + ".mp4"

    old_filename = None
    list_of_files = glob.glob( os.path.normpath ( folder + '/*.mp4' ) ) 
    if len(list_of_files)>0:
        old_filename = max(list_of_files, key=os.path.getctime)

    if old_filename:
        dt= time.time() -  os.path.getctime( old_filename )
        if "interval" in hondartza and hondartza["interval"] > dt:
            print(" %s denbora gutxi pasa da. (%d)" % (hondartza['izena'], dt ) )
            return

    hondartza['url']=hondartza['url'].replace( '${rand}', str(random.randint(0,50000)) )
    print("url: " + hondartza['url'] + " >>> " +  "/tmp/"+ new_name  )

    r=get_video( hondartza['url'], "/tmp/"+ new_name  , 0,  int(data['conf']['capture_timeout'])) 
    if r:
        shutil.move( "/tmp/"+ new_name,  folder + "/" + new_name )
        
        

def get_image_webcam(hondartza):
    print("Image webcam")
    folder=data['conf']['path']+"/" +hondartza['izena']
    if not os.path.exists(folder):
        os.makedirs(folder,mode=0o777)

    new_image=str(int(time.time())) + ".jpg"
    new_slider=str(int(time.time())) + ".mp4"


    old_filename = None
    list_of_img_files = glob.glob( os.path.normpath ( folder + '/*.jpg' ) ) 
    if len(list_of_img_files)>0:
        old_filename = max(list_of_img_files, key=os.path.getctime)

    if old_filename:
        dt= time.time() -  os.path.getctime( old_filename )
        if "interval" in hondartza and hondartza["interval"] > dt:
            print(" %s denbora gutxi pasa da. (%d)" % (hondartza['izena'], dt ) )
            return
    print( "img jaso eta bideo berria sortu ")
    tmpf=os.path.normpath ( '/tmp/' + new_image  )
    newf=os.path.normpath ( folder + '/' + new_image  )
    
    if not get_image(hondartza['url'], tmpf ) or not os.path.isfile(tmpf):
        print("Irudia oker atera da!")
        if os.path.isfile(tmpf):
            os.remove(tmpf)
        return
    if old_filename and os.path.getsize(old_filename)==os.path.getsize(tmpf):
        if os.path.isfile(tmpf):
            os.remove(tmpf)
        print("Irudi berdina da.")
        return
    shutil.move( tmpf,newf)
    
    if len(list_of_img_files) + 1 < hondartza['length'] :
        print("Ez dago nahiko argazkirik")
        #return
    r=create_slide(  folder, "/tmp/"+ new_slider, hondartza['length'], hondartza['duration'] )
    if r:
        print("FFF: " + folder + "/" + new_slider )
        shutil.move( "/tmp/"+ new_slider ,  folder + "/" + new_slider )


#os.chdir(os.path.dirname(sys.argv[0]) + "/.." )
#print("ppp: " + os.getcwd())

#############################################################
#   NAGUSIA
#############################################################
                
non=os.path.abspath(os.path.dirname(os.sys.argv[0]))
os.chdir(non)

data={}
with open('./conf/webcam.json') as f:
    data = json.load(f)

if "hondartzak" in data:
    for hondartza in data['hondartzak']:
        print("\n\n**izena: " + hondartza['izena'] + "  " + str(datetime.now()) )
        if "type" in hondartza and hondartza['type']=="video":
            get_video_webcam(hondartza)
        elif "type" in hondartza and hondartza['type']=="image":
            get_image_webcam(hondartza)
        
        