#!/usr/bin/env python
# -*- coding: utf-8 -*-

##
# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U.
# This file is part of openmano
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##

"""
openmano server.
Main program that implements a reference NFVO (Network Functions Virtualisation Orchestrator).
It interfaces with an NFV VIM through its API and offers a northbound interface, based on REST (openmano API),
where NFV services are offered including the creation and deletion of VNF templates, VNF instances,
network service templates and network service instances.

It loads the configuration file and launches the http_server thread that will listen requests using openmano API.
"""

import time
import sys
import getopt
import yaml
from os import environ, path as os_path
from jsonschema import validate as js_v, exceptions as js_e
import logging
import logging.handlers as log_handlers
import socket

from yaml import MarkedYAMLError

from osm_ro import httpserver, nfvo, nfvo_db
from osm_ro.openmano_schemas import config_schema
from osm_ro.db_base import db_base_Exception
from osm_ro.wim.engine import WimEngine
from osm_ro.wim.persistence import WimPersistence
import osm_ro

__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
__date__ = "$26-aug-2014 11:09:29$"
__version__ = "6.0.2.post2"
version_date = "Sep 2019"
database_version = 39      # expected database schema version

global global_config
global logger


class LoadConfigurationException(Exception):
    pass


def load_configuration(configuration_file):
    default_tokens = {'http_port': 9090,
                      'http_host': 'localhost',
                      'http_console_proxy': True,
                      'http_console_host': None,
                      'log_level': 'DEBUG',
                      'log_socket_port': 9022,
                      'auto_push_VNF_to_VIMs': True,
                      'db_host': 'localhost',
                      'db_ovim_host': 'localhost'
                      }
    try:
        # Check config file exists
        with open(configuration_file, 'r') as f:
            config_str = f.read()
        # Parse configuration file
        config = yaml.load(config_str)
        # Validate configuration file with the config_schema
        js_v(config, config_schema)

        # Add default values tokens
        for k, v in default_tokens.items():
            if k not in config:
                config[k] = v
        return config

    except yaml.YAMLError as e:
        error_pos = ""
        if isinstance(e, MarkedYAMLError):
            mark = e.problem_mark
            error_pos = " at line:{} column:{}".format(mark.line + 1, mark.column + 1)
        raise LoadConfigurationException("Bad YAML format at configuration file '{file}'{pos}: {message}".format(
            file=configuration_file, pos=error_pos, message=e))
    except js_e.ValidationError as e:
        error_pos = ""
        if e.path:
            error_pos = " at '" + ":".join(map(str, e.path)) + "'"
        raise LoadConfigurationException("Invalid field at configuration file '{file}'{pos} {message}".format(
            file=configuration_file, pos=error_pos, message=e))
    except Exception as e:
        raise LoadConfigurationException("Cannot load configuration file '{file}' {message}".format(
            file=configuration_file, message=e))


def console_port_iterator():
    """
    this iterator deals with the http_console_ports
    returning the ports one by one
    """
    index = 0
    while index < len(global_config["http_console_ports"]):
        port = global_config["http_console_ports"][index]
        if type(port) is int:
            yield port
        else:  # this is dictionary with from to keys
            port2 = port["from"]
            while port2 <= port["to"]:
                yield port2
                port2 += 1
        index += 1


def usage():
    print("Usage: ", sys.argv[0], "[options]")
    print("      -v|--version: prints current version")
    print("      -c|--config [configuration_file]: loads the configuration file (default: openmanod.cfg)")
    print("      -h|--help: shows this help")
    print(
        "      -p|--port [port_number]: changes port number and overrides the port number in the configuration file (default: 9090)")
    print(
        "      -P|--adminport [port_number]: changes admin port number and overrides the port number in the configuration file (default: 9095)")
    print("      --log-socket-host HOST: send logs to this host")
    print("      --log-socket-port PORT: send logs using this port (default: 9022)")
    print("      --log-file FILE: send logs to this file")
    print(
        "      --create-tenant NAME: Try to creates this tenant name before starting, ignoring any errors as e.g. conflict")
    return


def set_logging_file(log_file):
    try:
        file_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=100e6, backupCount=9, delay=0)
        file_handler.setFormatter(log_formatter_simple)
        logger.addHandler(file_handler)
        # remove initial stream handler
        logging.root.removeHandler(logging.root.handlers[0])
        print ("logging on '{}'".format(log_file))
    except IOError as e:
        raise LoadConfigurationException(
            "Cannot open logging file '{}': {}. Check folder exist and permissions".format(log_file, e))


if __name__ == "__main__":
    # env2config contains environ variable names and the correspondence with configuration file openmanod.cfg keys.
    # If this environ is defined, this value is taken instead of the one at at configuration file
    env2config = {
        'RO_DB_HOST': 'db_host',
        'RO_DB_NAME': 'db_name',
        'RO_DB_USER': 'db_user',
        'RO_DB_PASSWORD': 'db_passwd',
        'RO_DB_OVIM_HOST': 'db_ovim_host',
        'RO_DB_OVIM_NAME': 'db_ovim_name',
        'RO_DB_OVIM_USER': 'db_ovim_user',
        'RO_DB_OVIM_PASSWORD': 'db_ovim_passwd',
        'RO_LOG_LEVEL': 'log_level',
        'RO_LOG_FILE': 'log_file',
    }
    # Configure logging step 1
    hostname = socket.gethostname()
    log_formatter_str = '%(asctime)s.%(msecs)03d00Z[{host}@openmanod] %(filename)s:%(lineno)s severity:%(levelname)s logger:%(name)s log:%(message)s'
    log_formatter_complete = logging.Formatter(log_formatter_str.format(host=hostname), datefmt='%Y-%m-%dT%H:%M:%S')
    log_format_simple = "%(asctime)s %(levelname)s  %(name)s %(thread)d %(filename)s:%(lineno)s %(message)s"
    log_formatter_simple = logging.Formatter(log_format_simple, datefmt='%Y-%m-%dT%H:%M:%S')
    logging.basicConfig(format=log_format_simple, level=logging.DEBUG)
    logger = logging.getLogger('openmano')
    logger.setLevel(logging.DEBUG)
    socket_handler = None
    # Read parameters and configuration file
    httpthread = None
    try:
        # load parameters and configuration
        opts, args = getopt.getopt(sys.argv[1:], "hvc:V:p:P:",
                                   ["config=", "help", "version", "port=", "vnf-repository=", "adminport=",
                                    "log-socket-host=", "log-socket-port=", "log-file=", "create-tenant="])
        port = None
        port_admin = None
        config_file = 'osm_ro/openmanod.cfg'
        vnf_repository = None
        log_file = None
        log_socket_host = None
        log_socket_port = None
        create_tenant = None

        for o, a in opts:
            if o in ("-v", "--version"):
                print ("openmanod version " + __version__ + ' ' + version_date)
                print ("(c) Copyright Telefonica")
                sys.exit()
            elif o in ("-h", "--help"):
                usage()
                sys.exit()
            elif o in ("-V", "--vnf-repository"):
                vnf_repository = a
            elif o in ("-c", "--config"):
                config_file = a
            elif o in ("-p", "--port"):
                port = a
            elif o in ("-P", "--adminport"):
                port_admin = a
            elif o == "--log-socket-port":
                log_socket_port = a
            elif o == "--log-socket-host":
                log_socket_host = a
            elif o == "--log-file":
                log_file = a
            elif o == "--create-tenant":
                create_tenant = a
            else:
                assert False, "Unhandled option"
        if log_file:
            set_logging_file(log_file)
        global_config = load_configuration(config_file)
        global_config["version"] = __version__
        global_config["version_date"] = version_date
        # Override parameters obtained by command line on ENV
        if port:
            global_config['http_port'] = port
        if port_admin:
            global_config['http_admin_port'] = port_admin
        if log_socket_host:
            global_config['log_socket_host'] = log_socket_host
        if log_socket_port:
            global_config['log_socket_port'] = log_socket_port

        # override with ENV
        for env_k, env_v in environ.items():
            try:
                if not env_k.startswith("RO_") or env_k not in env2config or not env_v:
                    continue
                global_config[env2config[env_k]] = env_v
                if env_k.endswith("PORT"):  # convert to int, skip if not possible
                    global_config[env2config[env_k]] = int(env_v)
            except Exception as e:
                logger.warn("skipping environ '{}={}' because exception '{}'".format(env_k, env_v, e))

        global_config["console_port_iterator"] = console_port_iterator
        global_config["console_thread"] = {}
        global_config["console_ports"] = {}
        if not global_config["http_console_host"]:
            global_config["http_console_host"] = global_config["http_host"]
            if global_config["http_host"] == "0.0.0.0":
                global_config["http_console_host"] = socket.gethostname()

        # Configure logging STEP 2
        if "log_host" in global_config:
            socket_handler = log_handlers.SocketHandler(global_config["log_socket_host"],
                                                        global_config["log_socket_port"])
            socket_handler.setFormatter(log_formatter_complete)
            if global_config.get("log_socket_level") \
                    and global_config["log_socket_level"] != global_config["log_level"]:
                socket_handler.setLevel(global_config["log_socket_level"])
            logger.addHandler(socket_handler)

        if log_file:
            global_config['log_file'] = log_file
        elif global_config.get('log_file'):
            set_logging_file(global_config['log_file'])

        logger.setLevel(getattr(logging, global_config['log_level']))
        logger.critical("Starting openmano server version: '%s %s' command: '%s'",
                        __version__, version_date, " ".join(sys.argv))

        for log_module in ("nfvo", "http", "vim", "wim", "db", "console", "ovim"):
            log_level_module = "log_level_" + log_module
            log_file_module = "log_file_" + log_module
            logger_module = logging.getLogger('openmano.' + log_module)
            if log_level_module in global_config:
                logger_module.setLevel(global_config[log_level_module])
            if log_file_module in global_config:
                try:
                    file_handler = logging.handlers.RotatingFileHandler(global_config[log_file_module],
                                                                        maxBytes=100e6, backupCount=9, delay=0)
                    file_handler.setFormatter(log_formatter_simple)
                    logger_module.addHandler(file_handler)
                except IOError as e:
                    raise LoadConfigurationException(
                        "Cannot open logging file '{}': {}. Check folder exist and permissions".format(
                            global_config[log_file_module], str(e)))
            global_config["logger_" + log_module] = logger_module

        # Initialize DB connection
        mydb = nfvo_db.nfvo_db()
        mydb.connect(global_config['db_host'], global_config['db_user'], global_config['db_passwd'],
                     global_config['db_name'])
        db_path = osm_ro.__path__[0] + "/database_utils"
        if not os_path.exists(db_path + "/migrate_mano_db.sh"):
            db_path = osm_ro.__path__[0] + "/../database_utils"
        try:
            r = mydb.get_db_version()
            if r[0] != database_version:
                logger.critical("DATABASE wrong version '{current}'. Try to upgrade/downgrade to version '{target}'"
                                " with '{db_path}/migrate_mano_db.sh {target}'".format(current=r[0],
                                                                                       target=database_version,
                                                                                       db_path=db_path))
                exit(-1)
        except db_base_Exception as e:
            logger.critical("DATABASE is not valid. If you think it is corrupted, you can init it with"
                            " '{db_path}/init_mano_db.sh' script".format(db_path=db_path))
            exit(-1)

        nfvo.global_config = global_config
        if create_tenant:
            try:
                nfvo.new_tenant(mydb, {"name": create_tenant})
            except Exception as e:
                if isinstance(e, nfvo.NfvoException) and e.http_code == 409:
                    pass  # if tenant exist (NfvoException error 409), ignore
                else:  # otherwise print and error and continue
                    logger.error("Cannot create tenant '{}': {}".format(create_tenant, e))

        # WIM module
        wim_persistence = WimPersistence(mydb)
        wim_engine = WimEngine(wim_persistence)
        # ---
        nfvo.start_service(mydb, wim_persistence, wim_engine)

        httpthread = httpserver.httpserver(
            mydb, False,
            global_config['http_host'], global_config['http_port'],
            wim_persistence, wim_engine
        )

        httpthread.start()
        if 'http_admin_port' in global_config:
            httpthreadadmin = httpserver.httpserver(mydb, True, global_config['http_host'],
                                                    global_config['http_admin_port'])
            httpthreadadmin.start()
        time.sleep(1)
        logger.info('Waiting for http clients')
        print('Waiting for http clients')
        print('openmanod ready')
        print('====================')
        time.sleep(20)
        sys.stdout.flush()

        # TODO: Interactive console must be implemented here instead of join or sleep

        # httpthread.join()
        # if 'http_admin_port' in global_config:
        #    httpthreadadmin.join()
        while True:
            time.sleep(86400)

    except KeyboardInterrupt as e:
        logger.info(str(e))
    except SystemExit:
        pass
    except getopt.GetoptError as e:
        logger.critical(str(e))  # will print something like "option -a not recognized"
        exit(-1)
    except LoadConfigurationException as e:
        logger.critical(str(e))
        exit(-1)
    except db_base_Exception as e:
        logger.critical(str(e))
        exit(-1)
    except nfvo.NfvoException as e:
        logger.critical(str(e), exc_info=True)
        exit(-1)
    nfvo.stop_service()
    if httpthread:
        httpthread.join(1)
