#!/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 controller
and host controllers  
"""

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['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()
