import click
import sys
import itertools
import cv2.gapi
import mtcnn
import logging
import os
import cv2
import numpy as np
import re
from matplotlib import pyplot as plt
import threading
from time import time
# from app import flask_app
# from flask import request

@click.command()

@click.argument('file_path')
@click.option('--save_path', '-o')
def main(file_paths, save_path=None):
    face_anonymizer(file_paths, save_path='')


logger = logging.Logger('app_logger', level=2)


def console_logger( anony_img, anony_fname):

    plt.imsave(fname=anony_fname, arr=anony_img)

    logger.log(msg='Mission Completed! Check your image file in the directory.', level=1)
    return anony_img

def bb_blur_pool(bb, img_file):
    nblocks = 3

    ys = abs(bb['box'][0])
    ye = ys + abs(bb['box'][2])
    xs = abs(bb['box'][1])
    xe = xs + abs(bb['box'][3])
    px_x = int((xe - xs) / nblocks) - 1 if int((xe - xs) / nblocks) % 2 == 0 else int((xe - xs) / nblocks)
    px_y = int((ye - ys) / nblocks) - 1 if int((ye - ys) / nblocks) % 2 == 0 else int((ye - ys) / nblocks)
    img_file[xs:xe, ys:ye] = cv2.GaussianBlur(img_file[xs:xe, ys:ye], (33, 33), sigmaX=nblocks, sigmaY=nblocks)
    for i in range(1, nblocks + 1):
        img_file[xs:xs+(px_x*i), ys:ys+(px_y*i)] = cv2.GaussianBlur(img_file[xs:xs+(px_x*i), ys:ys+(px_y*i)], (px_x,px_y), sigmaX=0,
                                                                    sigmaY=0)

def fc_anonymizer(face_bbs, img_file, anony_fname):

    logging.log(msg='There are {0} faces found!'.format(len(face_bbs)), level=2)
    print('There are {0} faces found!'.format(len(face_bbs)))

    threads = []
    for bb in face_bbs:
        cthread = threading.Thread(target=bb_blur_pool, args=(bb, img_file))
        cthread.start()
        threads.append(cthread)

    for t in range(len(face_bbs)):
        threads[t].join()

    console_logger(np.array(img_file, dtype=np.uint8), anony_fname)

def face_anonymizer(img_n, save_path=''):

    t_list = []
    start_t = time()  # beginning timestamp
    mtcnn_obj = mtcnn.MTCNN()
    anony_fname= ''
    if type(img_n) is list:
        for f in img_n:
            t = threading.Thread()
            t.start()

            f = os.path.abspath(f)
            fext = str.split(f, '.')
            fsep = '/'  # default
            if str.lower(sys.platform) == 'linux':
                fsep = '/'
            elif str.lower(sys.platform) == 'windows':
                fsep = '\\'

            last_part = fext[0].split(fsep)[-1] + '_anony'
            path_parts = fext[0].split(fsep)
            path_parts[-1] = last_part
            if save_path != '':
                if not os.path.exists(save_path):
                    anony_fname = save_path + fsep + last_part + '.' + fext[1]
                elif os.path.isdir(save_path):
                    return "Non-existing save path!"
            else:
                anony_fname = fsep.join(path_parts) + '.' + fext[1]

            img_f = np.array(plt.imread(f), dtype=np.uint8)

            face_bbs = mtcnn_obj.detect_faces(img_f)
            fc_fnd = len(face_bbs) > 0
            if not fc_fnd:
                logger.log(msg='Apologise. The image may not have humans’ faces.', level=1)
                print('Apologise. The image may not have humans’ faces.')
                return
                # flask app request response imp later
            else:
                print('Anonymized image will be saved to ', anony_fname)
                # f = open('/home/sisi/PycharmProjects/anony_face/resources/dataset/'), color='black'
                start_an = time()
                fc_anonymizer(face_bbs, img_f, anony_fname)
                print('Time taken to anonymize {0} face(s): {1} seconds.'.format(len(face_bbs), time() - start_an))

            t_list.append(t)

        for t in range(len(img_n)):
            t_list[t].join()
    else:
        img_n = os.path.abspath(img_n)
        fext = str.split(img_n, '.')
        fsep = '/' #default
        if str.lower(sys.platform) == 'linux':
            fsep = '/'
        elif str.lower(sys.platform) == 'windows':
            fsep = '\\'

        last_part = fext[0].split(fsep)[-1] + '_anony'
        path_parts = fext[0].split(fsep)
        path_parts[-1] = last_part

        if save_path != '':
            if not os.path.exists(save_path):
                anony_fname = save_path + fsep + last_part + '.' + fext[1]
            elif os.path.isdir(save_path):
                return "Non-existing save path!"
        else:
            anony_fname = fsep.join(path_parts) + '.' + fext[1]


        img_f = np.array(plt.imread(img_n), dtype=np.uint8)

        face_bbs = mtcnn_obj.detect_faces(img_f)
        fc_fnd = len(face_bbs) > 0
        if not fc_fnd:
            logger.log(msg='Apologise. The image may not have humans’ faces.', level=1)
            print('Apologise. The image may not have humans’ faces.')
            return
            # flask app request response imp later
        else:
            print('Anonymized image will be saved to ', anony_fname)
            # f = open('/home/sisi/PycharmProjects/anony_face/resources/dataset/'), color='black'
            start_an = time()
            fc_anonymizer(face_bbs, img_f, anony_fname)
            print('Time taken to anonymize {0} face(s): {1} seconds.'.format(len(face_bbs), time() - start_an))

        print('Time taken to resolve this program instance: {0} seconds.'.format(time() - start_t))
        logger.log(msg='Time taken to resolve this program instance: {0} seconds.'.format(time() - start_t), level=1)

if __name__ == '__main__':
    face_anonymizer(['/home/sisi/PycharmProjects/anony_face/app/resources/dataset/arrested.jpg',
                     '/home/sisi/PycharmProjects/anony_face/app/resources/dataset/peds_in_rain.jpg'])