import configparser
import os

import requests
from flask import Flask, render_template, request, send_file
from werkzeug.utils import secure_filename

from stark import run

app = Flask(__name__)
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'conllu'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


def create_default_configs():
    configs = {}
    # mandatory parameters
    configs['input_path'] = 'data/sl_ssj-ud_v2.4.conllu'
    configs['output'] = 'results/out_official.tsv'
    configs['tree_size'] = '2-4'
    configs['node_type'] = 'upos'

    # mandatory parameters with default value
    configs['internal_saves'] = './internal_saves'
    configs['cpu_cores'] = 12
    configs['complete_tree_type'] = True
    configs['dependency_type'] = True
    configs['node_order'] = True
    configs['association_measures'] = False

    configs['label_whitelist'] = []
    configs['root_whitelist'] = []

    configs['query'] = None

    configs['compare'] = None

    configs['frequency_threshold'] = 0
    configs['lines_threshold'] = None

    configs['continuation_processing'] = False

    configs['nodes_number'] = True
    configs['print_root'] = True

    if configs['compare'] is not None:
        configs['other_input_path'] = configs['compare']
    return configs


def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/upload')
def upload_file2():
    return render_template('upload.html')


@app.route('/uploader', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['file']
        f.save(secure_filename(f.filename))
        return 'file uploaded successfully'


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        form = request.form
        a = request
        configs = {}
        # mandatory parameters
        configs['input_path'] = 'data/sl_ssj-ud_v2.4.conllu'
        validation = {}


        # handling input
        if 'file' in request.files and request.files['file']:
            # TODO ADD OPTION FOR MULTIPLE FILES - ZIP!
            # store file
            f = request.files['file']
            input_path = os.path.join('media', secure_filename(f.filename))
            f.save(input_path)

            configs['input_path'] = input_path

            if 'input_url' in form and form['input_url']:
                validation['file'] = 'Please insert either input url or file, not both of them.'
                validation['input_url'] = 'Please insert either input url or file, not both of them.'
            # TODO OPTIONALLY ADD conllu FILE CHECK
        elif 'input_url' in form and form['input_url']:
            try:
                input_path = os.path.join('media', 'input.conllu')
                response = requests.get(form['input_url'])
                open(input_path, "wb").write(response.content)
                configs['input_path'] = input_path
            except:
                validation['input_url'] = 'Incorrect URL!'
        else:
            validation['file'] = 'Please insert either input url or provide a file.'
            validation['input_url'] = 'Please insert either input url or provide a file.'

        tree_size_min = None
        if 'tree_size_min' in form:
            tree_size_min = form['tree_size_min']

        tree_size_max = None
        if 'tree_size_max' in form:
            tree_size_max = form['tree_size_max']

        def validate_tree_size(tree_size_min, tree_size_max):
            if tree_size_min is None or tree_size_max is None:
                validation['tree_size'] = 'Please provide information about minimum and maximum tree size.'
                return False

            if int(tree_size_min) > int(tree_size_max):
                validation['tree_size'] = 'Tree size minimum should be smaller than tree size maximum.'
                return False
            return True

        if validate_tree_size(tree_size_min, tree_size_max):
            configs['tree_size'] = f'{tree_size_min}-{tree_size_max}' if tree_size_min != tree_size_max else f'{tree_size_min}'

        def validate_node_type(node_type):
            # TODO EXPAND NODE TYPE
            node_type_options = {'upos', 'form', 'lemma', 'upos', 'xpos', 'feats', 'deprel'}
            if len(node_type) == 0:
                validation['node_type'] = 'Please provide information about node type.'
                return False

            for el in node_type:
                if el not in node_type_options:
                    validation['node_type'] = f'Node option {el} is not supported. Please enter valid options.'
                    return False

            return True

        # TODO radio button (maybe checkbutton)
        node_type = []
        if 'node_type' in form:
            node_type = form['node_type']

        if validate_node_type(node_type):
            configs['node_type'] = '+'.join(node_type)

        # mandatory parameters with default value
        configs['internal_saves'] = None

        # TODO depends on computer
        configs['cpu_cores'] = 12

        # TODO FINALIZE THIS!
        configs['complete_tree_type'] = True
        configs['dependency_type'] = True
        configs['node_order'] = True
        configs['association_measures'] = False

        configs['label_whitelist'] = []
        configs['root_whitelist'] = []

        configs['query'] = None

        configs['compare'] = None

        configs['frequency_threshold'] = 0
        configs['lines_threshold'] = None

        configs['continuation_processing'] = False

        configs['nodes_number'] = True
        configs['print_root'] = True

        if configs['compare'] is not None:
            configs['other_input_path'] = configs['compare']

        ########################################
        #config = configparser.ConfigParser()
        #config.read('config.ini')

        # configs = read_configs(config, args)



        configs['output'] = os.path.join('media', 'result.tsv')
        configs['complete_tree_type'] = form['complete'] == 'yes'

        run(configs)
        # TODO DELETE STORED FILE AFTER PROCESSING
        return send_file(configs['output'], as_attachment=True)
    # return render_template('index.html')
    return render_template('index.html')


if __name__ == '__main__':
    app.run(debug=True)
