import DataBase.mongoDB as DataBase
import RegularExpressionParser.Parser as Parser
import re
import Crawler.Scrape as Scrape
from flask import Flask
from flask import request
from flask import abort
from flask import jsonify
from urllib.parse import urlparse, parse_qs
from flask_cors import CORS

app = Flask(__name__)
cors = CORS(app)
# app.config["DEBUG"] = True


@app.route("/", methods=['GET'])
def home():
    """ homepage of server """
    return "200: successfully connected to home page\n"


@app.route("/api/<collection>/", methods=["GET", "PUT", "POST", "DELETE"])
def data_base(collection):
    """ data base page of server """    
    if request.method == "GET":
        if collection == "book":
            url_parsed = urlparse(request.url)
            qs_parsed = parse_qs(url_parsed.query)
            if qs_parsed == {}:
                return DataBase.get_documents_json(0, {})
            result = search_document(["book.id:" + qs_parsed["id"][0]])
            if result == {"wrong": "True"}:
                abort(400, "Bad Request")
            else:
                return result
        elif collection == "author":
            url_parsed = urlparse(request.url)
            qs_parsed = parse_qs(url_parsed.query)
            if qs_parsed == {}:
                return DataBase.get_documents_json(1, {})
            result = search_document(["author.id:" + qs_parsed["id"][0]])
            if result == {"wrong": "True"}:
                abort(400, "Bad Request")
            else:
                return result
        elif collection == "search":
            url_parsed = urlparse(request.url)
            query = Parser.parse_url_to_query(url_parsed.query)
            qs_parsed = query.replace("q=", "")
            result = search_document(qs_parsed.split("&"))
            if result == {"wrong": "True"}:
                abort(400, "Bad Request")
            else:
                return result
        else:
            abort(400, "Bad Request")
    elif request.method == "PUT":
        if request.headers["Content-Type"] != "application/json":
            abort(415)
        json_update_info = request.json
        if collection == "book":
            opt = 0
        elif collection == "author":
            opt = 1
        else:
            abort(400, "Bad Request")
        DataBase.update_dicts(opt, request.args.to_dict(), json_update_info)
        return "200: PUT succeeded"
    elif request.method == "POST":
        if request.headers["Content-Type"] != "application/json":
            abort(415, "content should be JSON file")
        json_file = request.json
        if collection == "books":
            DataBase.insert_dicts(json_file, 0)
        elif collection == "authors":
            DataBase.insert_dicts(json_file, 1)
        elif collection == "book":
            DataBase.insert_document(json_file, 0)
        elif collection == "author":
            DataBase.insert_document(json_file, 1)
        elif collection == "scrape":
            param = request.args.to_dict()
            url = param["url"]
            max_book = param["max_book"]
            max_author = param["max_author"]
            Scrape.scrape_api(url, max_book, max_author)
            return "200: new data has been added to database"
        else:
            abort(400, "Bad Request")
        return "200: POST succeeded"
    elif request.method == "DELETE":
        identifier = request.args.to_dict()
        print(identifier)
        if collection == "book":
            opt = 0
        elif collection == "author":
            opt = 1
        else:
            abort(400, "Unknown Collection to DELETE") # 400 cz 404 is for non-existing directory!
        DataBase.clean(opt, identifier)
        return "200: DELETE succeeded"


def search_document(identifiers):
    """ function used to find one or several document in database """
    if len(identifiers) == 1:
        json_idt = Parser.parse_query_to_json(identifiers[0])
        if json_idt == {"wrong": "True"}:
            return {"wrong": "True"}
        print(json_idt)
        if re.search("^book.*", identifiers[0]):
            return DataBase.get_documents_json(0, json_idt)
        else:
            return DataBase.get_documents_json(1, json_idt)
    elif len(identifiers) == 3:
        if re.search("^book.*", identifiers[0]):
            if re.search("^author.*", identifiers[2]):
                print("Failed to find documentation: two statements are not pointing to the same collection")
                return {}
            else:
                opt = 0
        else:
            if re.search("^book.*", identifiers[2]):
                print("Failed to find documentation: two statements are not pointing to the same collection")
                return {}
            else:
                opt = 1
        json_idt1 = Parser.parse_query_to_json(identifiers[0])
        json_idt2 = Parser.parse_query_to_json(identifiers[2])
        if json_idt1 == {"wrong": "True"} or json_idt2 == {"wrong": "True"}:
            return {"wrong": "True"}
        if identifiers[1] == "AND":
            exp = {"$and": [json_idt1, json_idt2]}
        elif identifiers[1] == "OR":
            exp = {"$or": [json_idt1, json_idt2]}
        else:
            print("Failed to parse query: unknown operator for identifiers[1]")
            return {}
        print("exp:")
        print(exp)
        return DataBase.get_documents_json(opt, exp)
    else:
        print("Error, unknown identifiers")
        return {}


if __name__ == "__main__":
    app.run()