import io
import os
import sys

from flask import Flask, request, send_file, send_from_directory
from flask_restful import Api
import json
from werkzeug.utils import secure_filename
import shutil

# Local import
from utils.files_lib import get_full_path as get_root_dir_path, get_resources_data_path, remove_file
from utils.master_lib import get_unique_str
from bg_modifier.bg_modifier_api import BGModifierApi
from bg_modifier.m_data_helper import InputHandler, BGHelper, FilterHelper, BorderHelper
from cartoon_api.gan_cartoon_ready_model_helper import GanCartoonReadyModelHelper
from filter_res_api.filter_data import FilterData

configPath = get_root_dir_path("config.py")
if not os.path.exists(configPath):
    sys.exit('Missing configuration file :config.py')

app = Flask(__name__)
# app = Flask(__name__, static_url_path='/static')
app = Flask(__name__, static_folder='/static', static_url_path="/static")
app.config.from_object('config')
api = Api(app)
# File upload config
app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 * 3
app.config['UPLOAD_EXTENSIONS'] = ['.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.gif', '.GIF', '.PNG']
app.config['UPLOAD_PATH'] = '..\\resources\\uploads'


@app.route("/public/<path:path>" , methods=["GET"])
def static_dir__(path):
    return send_from_directory( directory = get_root_dir_path("static"), path=path)

@app.route("/filter_resource/<path:path>" , methods=["GET"])
def filter_resource_dir(path):
    return send_from_directory( directory = get_root_dir_path("filter_resources"), path=path)


@app.route("/data_validator", methods=["POST"])
def data_validator():
    try:
        val = json.dumps(InputHandler.from_data(request.form.get("magic_data")).toJson(), indent=4)
        return json.loads(val)
    except  ValueError as e:
        print("err", e)
        pass
    return "invalid data"


@app.route('/apply_magic', methods=['POST'])
def apply_magic():
    input_d_handler = None
    try:
        # x = json.loads(request.form.get("filter_obj"))
        input_d_handler = InputHandler.from_data(request.form.get("magic_data"))
    except  ValueError as e:
        print("err", e)
        pass

    if input_d_handler is None:
        return json.dumps({"status": "error", "error": "No Action found"}), 400

    uploaded_file = request.files['org_input_file']

    filename = secure_filename(uploaded_file.filename)
    if filename != '':
        file_ext = os.path.splitext(filename)[1]
        if file_ext not in app.config['UPLOAD_EXTENSIONS']:
            return json.dumps({"status": "error", "error": "Invalid file extension"}), 400

        if not os.path.exists(app.config['UPLOAD_PATH']): os.mkdir(app.config['UPLOAD_PATH'])

        inputFilePath = os.path.join(app.config['UPLOAD_PATH'],
                                     get_unique_str(old_name=uploaded_file.filename, file_ext=file_ext))
        inputOrgFilePath = os.path.join(app.config['UPLOAD_PATH'],
                                        get_unique_str(old_name=uploaded_file.filename, file_ext=file_ext,
                                                       extra_value="-org"))

        uploaded_file.save(inputFilePath)
        shutil.copy(inputFilePath, inputOrgFilePath)

        # uploaded_file.save(inputOrgFilePath)

        result = inputFilePath
        for magic in input_d_handler.magic_list:

            if isinstance(magic, BGHelper):
                print("---doing----", magic.action_type)
                bg_modifier = BGModifierApi()
                bg_modifier.bg_remove(input_path=result, output_path=result , magic=magic)
                # result = inputFilePath
                # pass

            elif isinstance(magic, FilterHelper):
                print("---doing----", magic.action_type)
                model = GanCartoonReadyModelHelper(input_file=result, style=magic.filter_name,
                                                   output_dir=get_resources_data_path("ot-result"))
                try:
                    result = model.applyFilter()
                except:
                    pass

            elif isinstance(magic, BorderHelper):
                print("---doing----", magic.action_type)
                bg_modifier = BGModifierApi()
                bg_modifier.add_border_to_image(input_path=result, output_path=result, border_width=magic.border_width,
                                                border_color_value=magic.border_color_value)

        if result is not None:
            # print("Output:", result)

            return_data = io.BytesIO()
            with open(result, 'rb') as fo:
                return_data.write(fo.read())
                return_data.seek(0)

            try:
                remove_file(inputFilePath)
                remove_file(result)
                remove_file(inputOrgFilePath)
            except:
                pass
            print("--Done with success--")
            return send_file(return_data, download_name='out-put.png')

    print("--Done with error--")
    return json.dumps({"status": "error", "error": "Invalid file"}), 400


@app.route("/", methods=["GET"])
def home():
    return "<h1>Face Detection Master</h1><p>This site is a prototype API for Face-detection sample.</p>"


api.add_resource(FilterData, "/filterData/")

app.run(
    # host=IP_ADDRESS, port=PORT
)
