#!/usr/bin/env python

# -*- coding: UTF-8 -*-

'''
This script is a command line implementation for RackHD
'''

import os
import re
import json
import urlparse
from utils import rackhd_services as rackhd_services
from utils import arg_utils as arg_utils
from utils import arg_parser as arg_parser
from utils import local_utils as local_utils
from utils.mongo_utils import mongo as mongo
import http_request as http_request

#return a tuple with 0: recognized commands namespace and 1: unparsed commands
ARG_LIST, ARG_LIST_UNKNOWN = arg_parser.parse_arguments()

def operate_rackhd_service(operator, services):
    '''
    Operate RackHD services.
    '''
    operator = operator + '_rackhd_services'
    if services == 'all':
        services = None
    rackhd = rackhd_services.RackhdServices(services)
    getattr(rackhd, operator)()

def parse_api_options(args):
    '''
    Parse API operatinon options
    :param <Object> args: Parsed RackHD CLI arguments
    '''
    address = {
        'server': '172.31.128.1',
        'port': '9090',
        'protocol': 'http'
    }
    # Example api /api/current/nodes/<id>/workflows/action
    api = {
        'opr': args.opr or 'nodes',
        'id':  args.identity or '',
        'subopr': args.subopr or '',
        'param': args.param or ''
    }
    api_ver = args.ver or 'current'
    api_string = 'api'
    query = ''

    #if args.header and args.header != 'application/json':
        #header = args.header
    #else:
        #header = {'content-type': 'application/json'}
    options = {
        'method': args.method,
        # GET, DELETE don't require header
        'url': None,
        'header': args.header,
        'payload': args.payload or ''
    }
    url_path = '/{}/{}'.format(api_string, api_ver)
    if args.api: # User can specify api url
        url_path = os.path.join(url_path, args.api)
    else:
        url_path = os.path.join(url_path, api['opr'], api['id'], api['subopr'], api['param'])
    if url_path.endswith('/'):
        url_path = url_path[:-1]
    netloc = '{}:{}'.format(address['server'], address['port'])
    if args.graph:
        args.query = 'name={}'.format(args.graph)
    if args.query:
        query = args.query
    url = urlparse.urlunparse((
        address['protocol'], # scheme
        netloc,
        url_path, #path
        '', #params
        query, #query
        False #fragment
    ))
    options['url'] = url
    return options

def parse_position_args(unknown_args, known_args):
    '''
    Parse and combine all arguments
    :param unknown_args: tuple from argparse parse_known_args methods
    :param known_args: NameSpace object from argparse parse_known_args methods
    '''
    # Supported unknow commands
    arg = unknown_args[0]
    pattern = re.compile("^[a-z0-9]{24}$")
    if pattern.match(arg):
        parser = getattr(arg_utils, 'parse_position_identity_args')
    else:
        assert arg in ['node', 'sku', 'service', 'test', 'install', 'sku', \
                       'log', 'config', 'mongo'],\
            'Position argument {} is not supported'.format(arg)
        parser = getattr(arg_utils, 'parse_position_{}_args'.format(arg))
    args = parser(unknown_args, known_args)
    return args

def api_output_view(result, args, options):
    """
    Test
    """
    content = {}
    if args.min:
        payload_config = local_utils.get_configurations('payload_min.json')
        items = payload_config[args.opr]
        print type(items)
        for value in result.content:
            print value
            for item in items:
                content[item] = value[item]
    else:
        content = result.content

    print "{{\"data\": {}, \"_api\": \"-X {} -H {} {}\", \"_status\": {}}}".format(
        content or "\"\"", options["method"], options["header"],
        result.url, result.status_code
    )


def run():
    """
    Run commands
    """
    arg_utils.parse_all_known(ARG_LIST)
    if ARG_LIST_UNKNOWN:
        parse_position_args(ARG_LIST_UNKNOWN, ARG_LIST)
    if ARG_LIST.service:
        arg_utils.parse_position_service_args(ARG_LIST_UNKNOWN, ARG_LIST)
        operate_rackhd_service(ARG_LIST.service, ARG_LIST.services)
    elif ARG_LIST.test:
        pass
    elif ARG_LIST.log:
        pass
    elif ARG_LIST.mongo:
        print mongo.find_doc_by_id(ARG_LIST.mongo)
    elif ARG_LIST.opr:
        options = parse_api_options(ARG_LIST)
        res = http_request.request(options)
        api_output_view(res, ARG_LIST, options)

if __name__ == '__main__':
    run()

f5cfe6e9c245e3bacf72bf54f5a4000c9c6b9752
#!/usr/bin/env python

# -*- coding: UTF-8 -*-

'''
This script is a command line implementation for RackHD
'''

import os
import re
import json
import urlparse
from utils import rackhd_services as rackhd_services
from utils import arg_utils as arg_utils
from utils import arg_parser as arg_parser
from utils import local_utils as local_utils
from utils.mongo_utils import mongo as mongo
import http_request as http_request

#return a tuple with 0: recognized commands namespace and 1: unparsed commands
ARG_LIST, ARG_LIST_UNKNOWN = arg_parser.parse_arguments()

def operate_rackhd_service(operator, services):
    '''
    Operate RackHD services.
    '''
    operator = operator + '_rackhd_services'
    if services == 'all':
        services = None
    rackhd = rackhd_services.RackhdServices(services)
    getattr(rackhd, operator)()

def parse_api_options(args):
    '''
    Parse API operatinon options
    :param <Object> args: Parsed RackHD CLI arguments
    '''
    address = {
        'server': '172.31.128.1',
        'port': '9090',
        'protocol': 'http'
    }
    # Example api /api/current/nodes/<id>/workflows/action
    api = {
        'opr': args.opr or 'nodes',
        'id':  args.identity or '',
        'subopr': args.subopr or '',
        'param': args.param or ''
    }
    api_ver = args.ver or 'current'
    api_string = 'api'
    query = ''

    #if args.header and args.header != 'application/json':
        #header = args.header
    #else:
        #header = {'content-type': 'application/json'}
    options = {
        'method': args.method,
        # GET, DELETE don't require header
        'url': None,
        'header': args.header,
        'payload': args.payload or ''
    }
    url_path = '/{}/{}'.format(api_string, api_ver)
    if args.api: # User can specify api url
        url_path = os.path.join(url_path, args.api)
    else:
        url_path = os.path.join(url_path, api['opr'], api['id'], api['subopr'], api['param'])
    if url_path.endswith('/'):
        url_path = url_path[:-1]
    netloc = '{}:{}'.format(address['server'], address['port'])
    if args.graph:
        args.query = 'name={}'.format(args.graph)
    if args.query:
        query = args.query
    url = urlparse.urlunparse((
        address['protocol'], # scheme
        netloc,
        url_path, #path
        '', #params
        query, #query
        False #fragment
    ))
    options['url'] = url
    return options

def parse_position_args(unknown_args, known_args):
    '''
    Parse and combine all arguments
    :param unknown_args: tuple from argparse parse_known_args methods
    :param known_args: NameSpace object from argparse parse_known_args methods
    '''
    # Supported unknow commands
    arg = unknown_args[0]
    pattern = re.compile("^[a-z0-9]{24}$")
    if pattern.match(arg):
        parser = getattr(arg_utils, 'parse_position_identity_args')
    else:
        assert arg in ['node', 'sku', 'service', 'test', 'install', 'sku', \
                       'log', 'config', 'mongo'],\
            'Position argument {} is not supported'.format(arg)
        parser = getattr(arg_utils, 'parse_position_{}_args'.format(arg))
    args = parser(unknown_args, known_args)
    return args

def api_output_view(result, args, options):
    """
    Test
    """
    content = {}
    if args.min:
        payload_config = local_utils.get_configurations('payload_min.json')
        items = payload_config[args.opr]
        print type(items)
        for value in result.content:
            print value
            for item in items:
                content[item] = value[item]
    else:
        content = result.content

    print "{{\"data\": {}, \"_api\": \"-X {} -H {} {}\", \"_status\": {}}}".format(
        content or "\"\"", options["method"], options["header"],
        result.url, result.status_code
    )


def run():
    """
    Run commands
    """
    arg_utils.parse_all_known(ARG_LIST)
    if ARG_LIST_UNKNOWN:
        parse_position_args(ARG_LIST_UNKNOWN, ARG_LIST)
    if ARG_LIST.service:
        arg_utils.parse_position_service_args(ARG_LIST_UNKNOWN, ARG_LIST)
        operate_rackhd_service(ARG_LIST.service, ARG_LIST.services)
    elif ARG_LIST.test:
        pass
    elif ARG_LIST.log:
        pass
    elif ARG_LIST.mongo:
        print mongo.find_doc_by_id(ARG_LIST.mongo)
    elif ARG_LIST.opr:
        options = parse_api_options(ARG_LIST)
        res = http_request.request(options)
        api_output_view(res, ARG_LIST, options)

if __name__ == '__main__':
    run()
