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

"""
    Provides script interface to manage user data. This is temporary


    This script:
        Has a number of subcommands to manage the userdata.
"""
from __future__ import absolute_import

import sys as _sys
import os
import argparse as _argparse

from smipyping import Explorer, TargetsData

from smipyping._configfile import read_config
from smipyping.config import DEFAULT_CONFIG_FILE, DEFAULT_DBTYPE
from smipyping._cliutils import SmartFormatter as _SmartFormatter


def create_explore_parser(prog):
    """Create the cmd line parser for the explore functions"""

    usage = '%(prog)s [options] server'
    desc = 'Explore WBEM servers in the defined database for general ' \
           'information about each server.'
    epilog = """
Examples:
  %s -u 10.1.134.25
  %s -T 4
  %s        # explores all servers in the base

""" % (prog, prog, prog)

    argparser = _argparse.ArgumentParser(
        prog=prog, usage=usage, description=desc, epilog=epilog,
        formatter_class=_SmartFormatter)

    pos_arggroup = argparser.add_argument_group(
        'Positional arguments')

    server_arggroup = argparser.add_argument_group(
        'Server related options',
        'Specify the server either by host address or database targetID')
    pos_arggroup.add_argument(
        '-u', '--uri', metavar='URI', nargs='?',
        help='Optional host name or ip address of wbem servers to explore '
             'schema:address:')
    server_arggroup.add_argument(
        '-T', '--target_id', dest='target_id',
        metavar='TargetId',
        type=int,
        help='R|If this argument is set, the value is a user id\n'
             'instead of an server url as the source for the test. In\n'
             'this case, namespace, user, and password arguments are\n'
             'derived from the user data rather than cli input')
    server_arggroup.add_argument(
        '-t', '--timeout', dest='timeout', metavar='timeout', type=int,
        default=20,
        help='R|Timeout of the completion of WBEM Server operation\n'
             'in seconds(integer between 0 and 300).\n'
             'Default: 20 seconds')

    general_arggroup = argparser.add_argument_group(
        'General options')
    general_arggroup.add_argument(
        '-f', '--config_file', metavar='CONFIG_FILE',
        default=DEFAULT_CONFIG_FILE,
        help=('Configuration file to use for config information. '
              'Default=%s' % DEFAULT_CONFIG_FILE))
    general_arggroup.add_argument(
        '-D', '--dbtype', metavar='DBTYPE',
        default=DEFAULT_DBTYPE,
        help=('DBTYPE to use. Default=%s' % DEFAULT_DBTYPE))
    general_arggroup.add_argument(
        '--no_ping', '-n', action='store_true', default=False,
        help='R|Do not ping for server as first test. Executing the\n'
             'ping often shortens the total response time.')
    general_arggroup.add_argument(
        '--threaded', action='store_true', default=False,
        help='If set use threaded code to explore in parallel')
    general_arggroup.add_argument(
        '--verbose', '-v', action='store_true', default=False,
        help='Verbosity level')
    general_arggroup.add_argument(
        '--debug', '-d', action='store_true',
        help='Display detailed connection information')

    return argparser


def main(prog):
    """
        Parse the command line and execute the explorer with the results
        of the parse
    """
    logfile = '%s.log' % prog

    argparser = create_explore_parser(prog)

    args = argparser.parse_args()

    if args.verbose:
        print('args %s' % args)

    db_config = read_config(args.config_file, args.dbtype, args.verbose)
    db_config['directory'] = os.path.dirname(args.config_file)
    target_data = TargetsData.factory(db_config, args.dbtype, args.verbose)

    # print('target_data %r' % target_data)

    hosts = target_data.get_hostid_list()

    # print('hosts %s' % hosts)

    filtered_hosts = []

    # TODO make this list comprehension
    if args.uri and args.target_id:
        print('ERROR: Use either uri or target_id option. They are exclusive')
        return 1
    if args.uri:
        for host in hosts:
            if host == args.wbemserver:
                filtered_hosts.append(host)
        if len(filtered_hosts) == 0:
            raise ValueError('Ip address %s not in data base' % args.wbemserver)
    elif args.target_id:
        target = target_data[args.target_id]
        filtered_hosts.append(target['IPAddress'])
    else:
        filtered_hosts = hosts

    targets = []
    for host in filtered_hosts:
        if args.verbose:
            print('targets extend host %s, rtns %s' %
                  (host, target_data.get_target_for_host(host)))

        targets.extend(target_data.get_target_for_host(host))
    if args.verbose:
        print('targets %s 0 %s ' % (targets, type(targets[0])))

    targets = set(targets)

    if args.verbose:
        print('targets after set %s' % targets)

    ping = False if args.no_ping else True

    logfile = '%s.log' % prog

    if args.verbose:
        print('args %s' % args)

    explore = Explorer(prog, target_data, logfile=logfile, verbose=args.verbose,
                       ping=ping, threaded=True)

    servers = explore.explore_servers(targets)

    # print results
    explore.report_server_info(servers, target_data)

    return 0


if __name__ == '__main__':
    prog_name = os.path.basename(_sys.argv[0])
    _sys.exit(main(prog_name))
