#
# Aura Engine API (https://gitlab.servus.at/aura/engine-api)
#
# Copyright (C) 2020 - The Aura Engine Team.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import sys
import os
import atexit

sys.path.append(os.path.join(os.path.dirname(__file__), '..'))

import connexion

import meta
from base.config    import AuraConfig
from base.logger    import AuraLogger
from base.node      import NodeType
from rest           import encoder
from service        import ApiService
from sync           import SyncJob
from models         import db, ma

# Read command line parameters

config_file = None

for arg in sys.argv:
    if arg.startswith("config="):
        config_file = arg.split("config=")[1]

# App Initialization

config = AuraConfig(config_file)
logger = AuraLogger(config, "engine-api").logger
sync_job = None

def build_app(app):
    app.json_encoder = encoder.JSONEncoder
    app.config["SQLALCHEMY_DATABASE_URI"] = config.get_database_uri()
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    app.config['ENV'] = "development"
    app.config['FLASK_ENV'] = "development"
    if config.get("debug_flask") == "true":
        app.config['DEBUG'] = True
    db.init_app(app)
    ma.init_app(app)
    return app

api = connexion.App(__name__, specification_dir='rest/swagger', arguments={'title': 'AURA Engine API'})
api.add_api('swagger.yaml', pythonic_params=True)
app = build_app(api.app)


def startup():
    """
    Startup Server.
    """
    port = config.get("api_port")
    api.run(port=port)


def shutdown():
    """
    Called when the application shuts down.
    """
    sync_job.exit()


with app.app_context():
    """
    Initialize Server.
    """
    db.create_all()

    # Evaluate deployment mode
    node_type = NodeType.MAIN
    if config.get("host_id") == 0:
        node_type = NodeType.SYNC

    service = ApiService(config, logger, node_type)
    app.config['SERVICE'] = service

    # Run sync job only in SYNC NODE mode
    if node_type == NodeType.SYNC:
        if config.get("enable_federation") == "false":
            logger.info("Node synchronization disabled")
        else:
            sync_job = SyncJob(config, logger, app)
            sync_job.start()

    atexit.register(shutdown)
    type = "MAIN"
    if node_type == NodeType.SYNC:
        type = "SYNC"
    federation = "enabled"
    if config.get("enable_federation") == "false":
        federation = "disabled"
    splash = "\n\n        ░E░N░G░I░N░E░░░A░P░I░ - v%s running as %s node - Federation %s.\n\n" % (meta.__version__, type, federation)
    logger.info(splash)


if __name__ == '__main__':
    startup()