# -*- coding: utf-8 -*-

#  This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
#    Copyright (C) 2018-2020 OzzieIsaacs
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program. If not, see <http://www.gnu.org/licenses/>.

import traceback

from flask import render_template
from werkzeug.exceptions import default_exceptions
try:
    from werkzeug.exceptions import FailedDependency
except ImportError:
    from werkzeug.exceptions import UnprocessableEntity as FailedDependency

from . import config, app, logger, services


log = logger.create()

# custom error page

def error_http(error):
    headers = {'WWW-Authenticate': 'Basic realm="calibre-web"'} if error.code == 401 else {}
    return render_template('http_error.html',
                           error_code="Error {0}".format(error.code),
                           error_name=error.name,
                           issue=False,
                           goto_admin=False,
                           unconfigured=not config.db_configured,
                           instance=config.config_calibre_web_title
                           ), error.code, headers


def internal_error(error):
    if (isinstance(error.original_exception, AttributeError) and
        error.original_exception.args[0] == "'NoneType' object has no attribute 'query'"
        and error.original_exception.name == "query"):
        return render_template('http_error.html',
                               error_code="Database Error",
                               error_name='The library used is invalid or has permission errors',
                               issue=False,
                               goto_admin=True,
                               unconfigured=False,
                               error_stack="",
                               instance=config.config_calibre_web_title
                               ), 500
    return render_template('http_error.html',
                           error_code="500 Internal Server Error",
                           error_name='The server encountered an internal error and was unable to complete your '
                                      'request. There is an error in the application.',
                           issue=True,
                           goto_admin=False,
                           unconfigured=False,
                           error_stack=traceback.format_exc().split("\n"),
                           instance=config.config_calibre_web_title
                           ), 500


def init_errorhandler():
    # http error handling
    for ex in default_exceptions:
        if ex < 500:
            app.register_error_handler(ex, error_http)
        elif ex == 500:
            app.register_error_handler(ex, internal_error)

    if services.ldap:
        # Only way of catching the LDAPException upon logging in with LDAP server down
        @app.errorhandler(services.ldap.LDAPException)
        # pylint: disable=unused-variable
        def handle_exception(e):
            log.debug('LDAP server not accessible while trying to login to opds feed')
            return error_http(FailedDependency())

