#!/usr/bin/env python

#
# Copyright 2015-2016 IBM Corporation
#
# 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.
#

##
# Whisk Admin command line interface
##

import os
import sys
import argparse
import json
import wskprop
import string
import random
import uuid
from subprocess import Popen, PIPE, STDOUT
try:
    import argcomplete
except ImportError:
    argcomplete = False
from wskutil import request

DB_PROTOCOL = 'DB_PROTOCOL'
DB_HOST     = 'DB_HOST'
DB_PORT     = 'DB_PORT'
DB_USERNAME = 'DB_USERNAME'
DB_PASSWORD = 'DB_PASSWORD'

DB_WHISK_AUTHS   = 'DB_WHISK_AUTHS'
DB_WHISK_ACTIONS = 'DB_WHISK_ACTIONS'

LOGS_DIR = 'WHISK_LOGS_DIR'

# SCRIPT_DIR is going to be traversing all links and point to tools/cli/wsk
CLI_DIR = os.path.dirname(os.path.realpath(sys.argv[0]))
# ROOT_DIR is the repository root
ROOT_DIR = os.path.join(os.path.join(CLI_DIR, os.pardir), os.pardir)

def main():
    requiredprops = [
        DB_PROTOCOL, DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD,
        DB_WHISK_AUTHS, DB_WHISK_ACTIONS,
        LOGS_DIR ]
    whiskprops = wskprop.importPropsIfAvailable(wskprop.propfile(ROOT_DIR))
    (valid, props, deferredInfo) = wskprop.checkRequiredProperties(requiredprops, whiskprops)

    exitCode = 0 if valid else 2
    if valid:
        try:
            args = parseArgs()
            if (args.verbose):
                print deferredInfo
            exitCode = {
              'user' : userCmd,
              'db'   : dbCmd,
              'syslog' : syslogCmd
            }[args.cmd](args, props)
        except Exception as e:
            print 'Exception: ', e
            print 'Informative: ', deferredInfo
            exitCode = 1
    sys.exit(exitCode)

def parseArgs():
    parser = argparse.ArgumentParser(description='OpenWhisk admin command line tool')
    parser.add_argument('-v', '--verbose', help='verbose output', action='store_true')
    subparsers = parser.add_subparsers(title='available commands', dest='cmd')

    propmenu = subparsers.add_parser('user', help='manage users')
    subparser = propmenu.add_subparsers(title='available commands', dest='subcmd')

    subcmd = subparser.add_parser('create', help='create a user and show authorization key')
    subcmd.add_argument('subject', help='the subject to create')
    subcmd.add_argument('-u', '--auth', help='the uuid:key to initialize the subject authorization key with')

    subcmd = subparser.add_parser('delete', help='delete a user')
    subcmd.add_argument('subject', help='the subject to delete')

    subcmd = subparser.add_parser('get', help='get authorization key for user')
    subcmd.add_argument('subject', help='the subject to get key for')

    subcmd = subparser.add_parser('whois', help='identify user from UUID (for convenience you can provide the entire authorization key')
    subcmd.add_argument('uuid', help='the user UUID to lookup')

    propmenu = subparsers.add_parser('db', help='work with dbs')
    subparser = propmenu.add_subparsers(title='available commands', dest='subcmd')

    subcmd = subparser.add_parser('get', help='get contents of database')
    subcmd.add_argument('database', help='the database name')
    subcmd.add_argument('-v', '--view', help='the view in the database to get')
    subcmd.add_argument('--docs', help='include document contents', action='store_true')

    propmenu = subparsers.add_parser('syslog', help='work with system logs')
    subparser = propmenu.add_subparsers(title='available commands', dest='subcmd')

    subcmd = subparser.add_parser('get', help='get logs for a transaction id')
    subcmd.add_argument('tid', help='the transaction id')
    subcmd.add_argument('component', help='component, one of [controller, invokerN] where N is invoker index')

    if argcomplete:
        argcomplete.autocomplete(parser)
    return parser.parse_args()

def userCmd(args, props):
    if args.subcmd == 'create':
        return createUserCmd(args, props)
    elif args.subcmd == 'delete':
        return deleteUserCmd(args, props)
    elif args.subcmd == 'get':
        return getUserCmd(args, props)
    elif args.subcmd == 'whois':
        return whoisUserCmd(args, props)
    else:
        print 'unknown command'
        return 2

def dbCmd(args, props):
    if args.subcmd == 'get':
        return getDbCmd(args, props)
    else:
        print 'unknown command'
        return 2

def syslogCmd(args, props):
    if args.subcmd == 'get':
        return getLogsCmd(args, props)
    else:
        print 'unknown command'
        return 2
  
def createUserCmd(args, props):
    protocol = props[DB_PROTOCOL]
    host     = props[DB_HOST]
    port     = props[DB_PORT]
    username = props[DB_USERNAME]
    password = props[DB_PASSWORD]
    database = props[DB_WHISK_AUTHS]

    subject = args.subject.strip()
    if len(subject) < 5:
        print 'Subject name must be at least 5 characters'
        return 2

    if args.auth:
        try:
            parts = args.auth.split(':')
            try:
                uid = str(uuid.UUID(parts[0], version = 4))
            except ValueError:
                print 'authorization id is not a valid UUID'
                return 2

            key = parts[1]
            if len(key) < 64:
                print 'authorization key must be at least 64 characters long'
                return 2
        except Exception as e:
            print 'failed to determine authorization id and key: %s' % e
            return 2
    else:
        uid = str(uuid.uuid4())
        key = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(64))

    doc = {
        '_id': args.subject,
        'uuid': uid,
        'key': key,
        'subject': subject
    }

    url = '%(protocol)s://%(host)s:%(port)s/%(database)s' % {
        'protocol': protocol,
        'host'    : host,
        'port'    : port,
        'database': database
    }
    body = json.dumps(doc)
    headers = {
        'Content-Type': 'application/json',
    }

    res = request('POST', url, body, headers, auth='%s:%s' % (username, password), verbose=args.verbose)
    if res.status in [201, 202]:
        print '%s:%s' % (doc['uuid'], doc['key'])
    else:
        print 'Failed to create subject (%s)' % res.read().strip()
        return 1

def getUserCmd(args, props):
    (doc, res) = getSubjecFromDb(args, props)

    if doc is not None:
        print '%s:%s' % (doc['uuid'], doc['key'])
        return 0
    else:
        print 'Failed to get subject (%s)' % res.read().strip()
        return 1

def getSubjecFromDb(args, props):
    protocol = props[DB_PROTOCOL]
    host     = props[DB_HOST]
    port     = props[DB_PORT]
    username = props[DB_USERNAME]
    password = props[DB_PASSWORD]
    database = props[DB_WHISK_AUTHS]

    url = '%(protocol)s://%(host)s:%(port)s/%(database)s/%(subject)s' % {
        'protocol': protocol,
        'host'    : host,
        'port'    : port,
        'database': database,
        'subject' : args.subject
    }

    headers = {
        'Content-Type': 'application/json',
    }

    res = request('GET', url, headers=headers, auth='%s:%s' % (username, password), verbose=args.verbose)
    if res.status == 200:
        doc = json.loads(res.read())
        return (doc, res)
    else:
        return (None, res)

def deleteUserCmd(args, props):
    protocol = props[DB_PROTOCOL]
    host     = props[DB_HOST]
    port     = props[DB_PORT]
    username = props[DB_USERNAME]
    password = props[DB_PASSWORD]
    database = props[DB_WHISK_AUTHS]

    if args.subject.strip() == '':
        print 'Subject must not be empty'
        return 2

    (rev, res) = getSubjecFromDb(args, props)
    if rev is None:
        print 'Failed to delete subject (%s)' % res.read().strip()
        return 1

    url = '%(protocol)s://%(host)s:%(port)s/%(database)s/%(subject)s?rev=%(rev)s' % {
        'protocol': protocol,
        'host'    : host,
        'port'    : port,
        'database': database,
        'subject' : args.subject,
        'rev'     : rev['_rev']
    }

    headers = {
        'Content-Type': 'application/json',
    }

    res = request('DELETE', url, headers=headers, auth='%s:%s' % (username, password), verbose=args.verbose)
    if res.status in [200, 202]:
        print 'Subject deleted'
    else:
        print 'Failed to delete subject (%s)' % res.read().strip()
        return 1

def whoisUserCmd(args, props):
    protocol = props[DB_PROTOCOL]
    host     = props[DB_HOST]
    port     = props[DB_PORT]
    username = props[DB_USERNAME]
    password = props[DB_PASSWORD]
    database = props[DB_WHISK_AUTHS]
    uuid     = args.uuid.split(':')[0]

    url = '%(protocol)s://%(host)s:%(port)s/%(database)s/_design/subjects/_view/uuids?key=["%(uuid)s"]' % {
        'protocol': protocol,
        'host'    : host,
        'port'    : port,
        'username': username,
        'database': database,
        'uuid'    : uuid
    }

    headers = {
        'Content-Type': 'application/json',
    }

    res = request('GET', url, headers=headers, auth='%s:%s' % (username, password), verbose=args.verbose)
    if res.status == 200:
        doc = json.loads(res.read())
        if 'rows' in doc and len(doc['rows']) > 0:
            for row in doc['rows']:
                if 'id' in row:
                    print row['id']
        else:
            print 'Subject id is not recognized'
        return 0
    print 'Failed to delete subject (%s)' % res.read().strip()
    return 1

def getDbCmd(args, props):
    protocol = props[DB_PROTOCOL]
    host     = props[DB_HOST]
    port     = props[DB_PORT]
    username = props[DB_USERNAME]
    password = props[DB_PASSWORD]

    if args.database == 'subjects':
        database = props[DB_WHISK_AUTHS]
    elif args.database == 'whisks':
        database = props[DB_WHISK_ACTIONS]
    else:
        database = args.database

    if args.view:
        try:
            parts = args.view.split('/')
            designdoc = parts[0]
            viewname  = parts[1]
        except:
            print 'view name "%s" is not formatted correctly, should be design/view' % args.view
            return 2

    url = '%(protocol)s://%(host)s:%(port)s/%(database)s%(design)s/%(index)s?include_docs=%(docs)s' % {
        'protocol': protocol,
        'host'    : host,
        'port'    : port,
        'database': database,
        'design'  : '/_design/' + designdoc +'/_view' if args.view else '',
        'index'   : viewname if args.view else '_all_docs',
        'docs'    : 'true' if args.docs else 'false' 
    }

    headers = {
        'Content-Type': 'application/json',
    }

    print 'getting contents for %s (%s)' % (database, args.view if args.view else 'primary index')
    res = request('GET', url, headers=headers, auth='%s:%s' % (username, password), verbose=args.verbose)
    if res.status == 200:
        table = json.loads(res.read())
        print json.dumps(table, sort_keys=True, indent=4, separators=(',', ': '))
        return 0
    print 'Failed to get database (%s)' % res.read().strip()
    return 1

def getLogsCmd(args, props):
    path = '%s/%s/%s_logs.log' % (props[LOGS_DIR], args.component, args.component)
    cmd = 'grep "\[#tid_%s\]" %s' % (args.tid, path)
    (output, error) = shell(cmd, verbose = args.verbose)
    if output:
        print output.strip()
    if error:
        print error.strip()
        return 1
    else:
        return 0

def shell(cmd, data=None, verbose=False):
    if verbose:
        print cmd
    if input:
        p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT, stdin=PIPE)
        out, err = p.communicate(input=data)
    else:
        out, err = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
    p.wait()
    return (out, err)

if __name__ == '__main__':
    main()
