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

##
# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
# This file is part of openvim
# 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
##

"""
This is the main program of openvim, it reads the configuration 
and launches the rest of threads: http clients, openflow controllers
and host controllers, network controller
"""

import osm_openvim.httpserver as httpserver
import osm_openvim.auxiliary_functions as af
import sys
import getopt
import time
import yaml
import os
from jsonschema import validate as js_v, exceptions as js_e
from osm_openvim.vim_schema import config_schema
import logging
import logging.handlers as log_handlers
import socket
import osm_openvim.ovim as ovim

__author__ = "Alfonso Tierno"
__date__ = "$10-jul-2014 12:07:15$"

global config_dic
global logger
logger = logging.getLogger('vim')


class LoadConfigurationException(Exception):
    pass


def load_configuration(configuration_file):
    default_tokens = {'http_port': 9080, 'http_host': 'localhost',
                      'of_controller_nets_with_same_vlan': True,
                      'host_ssh_keyfile': None,
                      'network_vlan_range_start': 1000,
                      'network_vlan_range_end': 4096,
                      'log_level': "DEBUG",
                      'log_level_db': "ERROR",
                      'log_level_of': 'ERROR',
                      'bridge_ifaces': {},
                      'network_type': 'ovs',
                      'ovs_controller_user': 'osm_dhcp',
                      'ovs_controller_file_path': '/var/lib/',
                      }
    try:
        # First load configuration from configuration file
        # Check config file exists
        if not os.path.isfile(configuration_file):
            raise LoadConfigurationException("Configuration file '{}' does not exists".format(configuration_file))

        # Read and parse file
        (return_status, code) = af.read_file(configuration_file)
        if not return_status:
            raise LoadConfigurationException("Error loading configuration file '{}': {}".format(
                configuration_file, code))
        config = yaml.load(code)
        js_v(config, config_schema)
        # Check default values tokens
        for k, v in default_tokens.items():
            if k not in config:
                config[k] = v
        # Check vlan ranges
        if config["network_vlan_range_start"] + 10 >= config["network_vlan_range_end"]:
            raise LoadConfigurationException(
                "Error at configuration file '{}'. Invalid network_vlan_range less than 10 elements".format(
                    configuration_file))
        return config
    except yaml.YAMLError as exc:
        error_pos = ""
        if hasattr(exc, 'problem_mark'):
            mark = exc.problem_mark
            error_pos = " at position: ({}:{})".format(mark.line + 1, mark.column + 1)
        raise LoadConfigurationException("Bad YAML format at configuration file '{}'{}: {}\n"
                                         "Use a valid yaml format. Indentation matters, "
                                         "and tabs characters are not valid".format(
                                                configuration_file, error_pos, exc))
    except js_e.ValidationError as exc:
        error_pos = ""
        if len(exc.path) > 0:
            error_pos = " at '{}'".format(":".join(map(str, exc.path)))
        raise LoadConfigurationException("Invalid field at configuration file '{}'{}: {}".format(
            configuration_file, error_pos, exc))

        # except Exception as e:
        #     raise LoadConfigurationException("Error loading configuration file '{}': {}".format(configuration_file, e))


def usage():
    print ("Usage: {} [options]".format(sys.argv[0]))
    print ("      -v|--version: prints current version")
    print ("      -c|--config FILE: loads the configuration file (default: osm_openvim/openvimd.cfg)")
    print ("      -h|--help: shows this help")
    print ("      -p|--port PORT: changes port number and overrides the port number in the configuration file "
           "(default: 908)")
    print ("      -P|--adminport PORT: changes admin port number and overrides the port number in the configuration "
           "file (default: not listen)")
    print ("      --dbname NAME: changes db_name and overrides the db_name in the configuration file")
    # 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")
    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)
        # logger.debug("moving logs to '%s'", global_config["log_file"])
        # 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__":
    hostname = socket.gethostname()
    # streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
    log_formatter_complete = logging.Formatter('%(asctime)s.%(msecs)03d00Z[{host}@openmanod] %(filename)s:%(lineno)s '
                                               'severity:%(levelname)s logger:%(name)s log:%(message)s'.format(
        host=hostname),
        datefmt='%Y-%m-%dT%H:%M:%S')
    log_format_simple = "%(asctime)s %(levelname)s  %(name)s %(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('openvim')
    logger.setLevel(logging.DEBUG)
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hvc:p:P:",
                                   ["config=", "help", "version", "port=", "adminport=", "log-file=", "dbname="])
    except getopt.GetoptError as err:
        # print help information and exit:
        logger.error("%s. Type -h for help", err)  # will print something like "option -a not recognized"
        # usage()
        sys.exit(2)

    port = None
    port_admin = None
    config_file = 'osm_openvim/openvimd.cfg'
    log_file = None
    db_name = None

    for o, a in opts:
        if o in ("-v", "--version"):
            print ("openvimd version {} {}".format(ovim.ovim.get_version(), ovim.ovim.get_version_date()))
            print ("(c) Copyright Telefonica")
            sys.exit(0)
        elif o in ("-h", "--help"):
            usage()
            sys.exit(0)
        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 in ("-P", "--dbname"):
            db_name = a
        elif o == "--log-file":
            log_file = a
        else:
            assert False, "Unhandled option"

    engine = None
    http_thread = None
    http_thread_admin = None

    try:
        if log_file:
            set_logging_file(log_file)
        # Load configuration file
        config_dic = load_configuration(config_file)
        if config_dic.get("dhcp_server"):
            if config_dic["dhcp_server"].get("key"):
                config_dic["dhcp_server"]["keyfile"] = config_dic["dhcp_server"].pop("key")
        if config_dic.get("image_path"):
            config_dic["host_image_path"] = config_dic.pop("image_path")
        elif not config_dic.get("host_image_path"):
            config_dic["host_image_path"] = '/opt/VNF/images'  # default value
        # print config_dic

        logger.setLevel(getattr(logging, config_dic['log_level']))
        logger.critical("Starting openvim server command: '%s'", sys.argv[0])
        # override parameters obtained by command line
        if port:
            config_dic['http_port'] = port
        if port_admin:
            config_dic['http_admin_port'] = port_admin
        if db_name:
            config_dic['db_name'] = db_name

        # check mode
        if 'mode' not in config_dic:
            config_dic['mode'] = 'normal'
            # allow backward compatibility of test_mode option
            if 'test_mode' in config_dic and config_dic['test_mode'] == True:
                config_dic['mode'] = 'test'
        if config_dic['mode'] == 'development' and config_dic['network_type'] == 'bridge' and \
                ('development_bridge' not in config_dic or
                         config_dic['development_bridge'] not in config_dic.get("bridge_ifaces", None)):
            error_msg = "'{}' is not a valid 'development_bridge', not one of the 'bridge_ifaces'".format(config_file)
            print (error_msg)
            logger.error(error_msg)
            exit(1)

        if config_dic['network_type'] == 'ovs' \
                and config_dic['ovs_controller_ip'][:4] == '127.':
                # and not (config_dic['mode'] == 'test' or config_dic['mode'] == "OF only"):

            error_msg = "Error: invalid value '{}' for ovs_controller_ip at {}. Use 'localhost' word instead "\
                        "of a loopback IP address".format(config_dic['ovs_controller_ip'], config_file)

            print ("!! {} ".format(error_msg))
            logger.error(error_msg)
            exit(1)

        if config_dic['mode'] != 'normal':
            print ('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
            print ("!! Warning, openvimd in TEST mode '{}'".format(config_dic['mode']))
            print ('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')

        config_dic['version'] = ovim.ovim.get_version()
        config_dic["logger_name"] = "openvim"

        engine = ovim.ovim(config_dic)
        engine.start_service()

        # Create thread to listen to web requests
        http_thread = httpserver.httpserver(engine, 'http', config_dic['http_host'], config_dic['http_port'],
                                            False, config_dic)
        http_thread.start()

        if 'http_admin_port' in config_dic:
            engine2 = ovim.ovim(config_dic)
            http_thread_admin = httpserver.httpserver(engine2, 'http-admin', config_dic['http_host'],
                                                      config_dic['http_admin_port'], True)
            http_thread_admin.start()
        else:
            http_thread_admin = None
        time.sleep(1)
        logger.info('Waiting for http clients')
        print ('openvimd ready')
        print ('====================')
        sys.stdout.flush()

        # TODO: Interactive console would be nice here instead of join or sleep

        r = ""
        while True:
            if r == 'exit':
                break
            elif r != '':
                print "type 'exit' for terminate"
            try:
                r = raw_input('> ')
            except EOFError:
                time.sleep(86400)

    except (KeyboardInterrupt, SystemExit):
        pass
    except (getopt.GetoptError, LoadConfigurationException, ovim.ovimException) as e:
        logger.critical(str(e))  # will print something like "option -a not recognized"
        exit(1)

    logger.info('Exiting openvimd')
    if engine:
        engine.stop_service()
    if http_thread:
        http_thread.join(1)
    if http_thread_admin:
        http_thread_admin.join(1)
    logger.debug("bye!")
    exit()
