#!/usr/bin/env python
#
# Copyright 2016 the original author or authors.
#
# 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.
#
import argparse
import os

import yaml
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks

from common.structlog_setup import setup_logging
from common.utils.dockerhelpers import get_my_containers_name
from common.utils.nethelpers import get_my_primary_local_ipv4
from connection_mgr import ConnectionManager

defs = dict(
    config=os.environ.get('CONFIG', './netconf.yml'),
    consul=os.environ.get('CONSUL', 'localhost:8500'),
    external_host_address=os.environ.get('EXTERNAL_HOST_ADDRESS',
                                         get_my_primary_local_ipv4()),
    netconf_port=os.environ.get('NETCONF_PORT', 1830),
    server_private_key_file=os.environ.get('SERVER_PRIVATE_KEY_FILE',
                                           'server.key'),
    server_public_key_file=os.environ.get('SERVER_PRIVATE_KEY_FILE',
                                          'server.key.pub'),
    client_public_keys_file=os.environ.get('CLIENT_PUBLIC_KEYS_FILE',
                                           'client_keys'),
    client_passwords_file=os.environ.get('CLIENT_PASSWORD_FILE',
                                         'client_passwords'),
    grpc_endpoint=os.environ.get('GRPC_ENDPOINT', 'localhost:50055'),
    fluentd=os.environ.get('FLUENTD', None),
    instance_id=os.environ.get('INSTANCE_ID', os.environ.get('HOSTNAME', '1')),
    internal_host_address=os.environ.get('INTERNAL_HOST_ADDRESS',
                                         get_my_primary_local_ipv4()),
    work_dir=os.environ.get('WORK_DIR', '/tmp/netconf')
)


def parse_args():
    parser = argparse.ArgumentParser()

    _help = ('Path to netconf.yml config file (default: %s). '
             'If relative, it is relative to main.py of ofagent.'
             % defs['config'])
    parser.add_argument('-c', '--config',
                        dest='config',
                        action='store',
                        default=defs['config'],
                        help=_help)

    _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
    parser.add_argument(
        '-C', '--consul', dest='consul', action='store',
        default=defs['consul'],
        help=_help)

    _help = ('<hostname> or <ip> at which netconf is reachable from '
             'outside the cluster (default: %s)' % defs[
                 'external_host_address'])
    parser.add_argument('-E', '--external-host-address',
                        dest='external_host_address',
                        action='store',
                        default=defs['external_host_address'],
                        help=_help)

    _help = ('<port> of netconf server (default: %s). (If not '
             'specified (None), the port from the config file is used'
             % defs['netconf_port'])
    parser.add_argument('-N', '--netconf_port',
                        dest='netconf_port',
                        action='store',
                        default=defs['netconf_port'],
                        help=_help)

    _help = (
    '<server private key file name> used by the netconf server. (If not '
    'specified (None), the file name from the config file is used (default: %s)'
    % defs['server_private_key_file'])
    parser.add_argument('-S', '--server_private_key_file',
                        dest='server_private_key_file',
                        action='store',
                        default=defs['server_private_key_file'],
                        help=_help)

    _help = ('<server public key file name> used by the netconf server. (If '
             'not specified (None), the file name from the config file is '
             'used (default: %s) '
             % defs['server_public_key_file'])
    parser.add_argument('-P', '--server_public_key_file',
                        dest='server_public_key_file',
                        action='store',
                        default=defs['server_public_key_file'],
                        help=_help)

    _help = ('<client public key file name> used by the netconf server. (If '
             'not specified (None), the file name from the config file is '
             'used(default: %s) '
             % defs['client_public_keys_file'])
    parser.add_argument('-X', '--client_public_keys_file',
                        dest='client_public_keys_file',
                        action='store',
                        default=defs['client_public_keys_file'],
                        help=_help)

    _help = ('<client password file name> used by the netconf server. (If '
             'not specified (None), the file name from the config file is '
             'used (default: %s) '
             % defs['client_passwords_file'])
    parser.add_argument('-U', '--client_passwords_file',
                        dest='client_passwords_file',
                        action='store',
                        default=defs['client_passwords_file'],
                        help=_help)

    _help = ('<hostname>:<port> to fluentd server (default: %s). (If not '
             'specified (None), the address from the config file is used'
             % defs['fluentd'])
    parser.add_argument('-F', '--fluentd',
                        dest='fluentd',
                        action='store',
                        default=defs['fluentd'],
                        help=_help)

    _help = ('gRPC end-point to connect to. It can either be a direct'
             'definition in the form of <hostname>:<port>, or it can be an'
             'indirect definition in the form of @<service-name> where'
             '<service-name> is the name of the grpc service as registered'
             'in consul (example: @voltha-grpc). (default: %s'
             % defs['grpc_endpoint'])
    parser.add_argument('-G', '--grpc-endpoint',
                        dest='grpc_endpoint',
                        action='store',
                        default=defs['grpc_endpoint'],
                        help=_help)

    _help = ('<hostname> or <ip> at which netconf server is reachable from '
             'inside the cluster (default: %s)' % defs[
                 'internal_host_address'])
    parser.add_argument('-H', '--internal-host-address',
                        dest='internal_host_address',
                        action='store',
                        default=defs['internal_host_address'],
                        help=_help)

    _help = ('unique string id of this netconf server instance (default: %s)'
             % defs['instance_id'])
    parser.add_argument('-i', '--instance-id',
                        dest='instance_id',
                        action='store',
                        default=defs['instance_id'],
                        help=_help)

    _help = 'omit startup banner log lines'
    parser.add_argument('-n', '--no-banner',
                        dest='no_banner',
                        action='store_true',
                        default=False,
                        help=_help)

    _help = "suppress debug and info logs"
    parser.add_argument('-q', '--quiet',
                        dest='quiet',
                        action='count',
                        help=_help)

    _help = 'enable verbose logging'
    parser.add_argument('-v', '--verbose',
                        dest='verbose',
                        action='count',
                        help=_help)

    _help = ('work dir to compile and assemble generated files (default=%s)'
             % defs['work_dir'])
    parser.add_argument('-w', '--work-dir',
                        dest='work_dir',
                        action='store',
                        default=defs['work_dir'],
                        help=_help)

    _help = ('use docker container name as netconf server instance id'
             ' (overrides -i/--instance-id option)')
    parser.add_argument('--instance-id-is-container-name',
                        dest='instance_id_is_container_name',
                        action='store_true',
                        default=False,
                        help=_help)

    args = parser.parse_args()

    # post-processing

    if args.instance_id_is_container_name:
        args.instance_id = get_my_containers_name()

    return args


def load_config(args):
    path = args.config
    if path.startswith('.'):
        dir = os.path.dirname(os.path.abspath(__file__))
        path = os.path.join(dir, path)
    path = os.path.abspath(path)
    with open(path) as fd:
        config = yaml.load(fd)
    return config


banner = r'''
 _   _      _                   __   ____
| \ | | ___| |_ ___ ___  _ __  / _| / ___|  ___ _ ____   _____ _ __
|  \| |/ _ \ __/ __/ _ \| '_ \| |_  \___ \ / _ \ '__\ \ / / _ \ '__|
| |\  |  __/ || (_| (_) | | | |  _|  ___) |  __/ |   \ V /  __/ |
|_| \_|\___|\__\___\___/|_| |_|_|   |____/ \___|_|    \_/ \___|_|
'''


def print_banner(log):
    for line in banner.strip('\n').splitlines():
        log.info(line)
    log.info('(to stop: press Ctrl-C)')


class Main(object):
    def __init__(self):

        self.args = args = parse_args()
        self.config = load_config(args)

        verbosity_adjust = (args.verbose or 0) - (args.quiet or 0)
        self.log = setup_logging(self.config.get('logging', {}),
                                 args.instance_id,
                                 verbosity_adjust=verbosity_adjust,
                                 fluentd=args.fluentd)

        # components
        self.connection_manager = None

        self.exiting = False

        if not args.no_banner:
            print_banner(self.log)

        self.startup_components()

    def start(self):
        self.start_reactor()  # will not return except Keyboard interrupt

    @inlineCallbacks
    def startup_components(self):
        self.log.info('starting-netconf-server')
        args = self.args
        self.connection_manager = yield ConnectionManager(
            args.consul,
            args.grpc_endpoint,
            args.netconf_port,
            args.server_private_key_file,
            args.server_public_key_file,
            args.client_public_keys_file,
            args.client_passwords_file).start()
        self.log.info('started-netconf-server')

    @inlineCallbacks
    def shutdown_components(self):
        """Execute before the reactor is shut down"""
        self.log.info('exiting-on-keyboard-interrupt')
        self.exiting = True
        if self.connection_manager is not None:
            yield self.connection_manager.stop()

    def start_reactor(self):
        reactor.callWhenRunning(
            lambda: self.log.info('twisted-reactor-started'))

        reactor.addSystemEventTrigger('before', 'shutdown',
                                      self.shutdown_components)
        reactor.run()


if __name__ == '__main__':
    Main().start()
