# -*- coding: utf-8 -*-
import flask
import time
import socket

from saas.library.python.errorbooster import ErrorBooster
from saas.tools.abcd.models.models import db, migrate
from saas.tools.abcd.api.blueprints import provider_api_bp, saas_quota_handles
from saas.tools.abcd.app.app_config import TestingConfig, ProductionConfig
from saas.tools.abcd.app.error_handlers import incorrect_args_400, unauthorized_401, forbidden_403, not_found_404, \
    already_exists_409, validation_error_422, unhandled_500


def prepare_flask_app(app=None, env_type="testing", tvm_enable=False):
    if not app:
        app = flask.Flask(__name__)
    app.logger.info('Running Flask server with environment: %s, tvm_enable=%s', env_type, tvm_enable)

    if env_type.lower() == "production":
        app.config.from_object(ProductionConfig())
    else:
        app.config.from_object(TestingConfig())

    app.config['TVM_ENABLE'] = tvm_enable

    # Blueprints
    app.register_blueprint(provider_api_bp.saas_abcd_api)
    app.register_blueprint(saas_quota_handles.saas_api)

    # Error handles
    app.register_error_handler(400, incorrect_args_400)
    app.register_error_handler(401, unauthorized_401)
    app.register_error_handler(403, forbidden_403)
    app.register_error_handler(404, not_found_404)
    app.register_error_handler(409, already_exists_409)
    app.register_error_handler(422, validation_error_422)
    app.register_error_handler(Exception, unhandled_500)

    # Other inits
    db.init_app(app)
    migrate.init_app(app, db)

    ErrorBooster('saas-abcd')

    # Customs

    @app.before_request
    def before():
        try:
            flask.request.start_time = time.time()
        except Exception as e:
            app.logger.exception(e)

    @app.after_request
    def after(response):
        try:
            response.headers['X-HOST'] = socket.getfqdn()
            stime_in_ms = str(int(1000 * (time.time() - flask.request.start_time)))
            response.headers['X-TIME'] = stime_in_ms
        except Exception as e:
            app.logger.exception(e)
        return response

    return app
