#!/usr/bin/env python
"""Executable Python script for testing the action proxy.
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

  This script is useful for testing the action proxy (or its derivatives)
  by simulating invoker interactions. Use it in combination with
  docker run <image> which starts up the action proxy.
  Example:
     docker run -i -t -p 8080:8080 dockerskeleton # locally built images may be referenced without a tag
     ./invoke.py init <action source file>
     ./invoke.py run '{"some":"json object as a string"}'

  For additional help, try ./invoke.py -h
"""

import os
import re
import sys
import json
import base64
import requests
import codecs
import argparse
try:
    import argcomplete
except ImportError:
    argcomplete = False

def main():
    try:
        args = parseArgs()
        exitCode = {
            'init' : init,
            'run'   : run
        }[args.cmd](args)
    except Exception as e:
        print(e)
        exitCode = 1
    sys.exit(exitCode)

def dockerHost():
    dockerHost = 'localhost'
    if 'DOCKER_HOST' in os.environ:
        try:
            dockerHost = re.compile('tcp://(.*):[\d]+').findall(os.environ['DOCKER_HOST'])[0]
        except Exception:
            print('cannot determine docker host from %s' % os.environ['DOCKER_HOST'])
            sys.exit(-1)
    return dockerHost

def containerRoute(args, path):
    return 'http://%s:%s/%s' % (args.host, args.port, path)

class objectify(object):
    def __init__(self, d):
        self.__dict__ = d

def parseArgs():
    parser = argparse.ArgumentParser(description='initialize and run an OpenWhisk action container')
    parser.add_argument('-v', '--verbose', help='verbose output', action='store_true')
    parser.add_argument('--host', help='action container host', default=dockerHost())
    parser.add_argument('-p', '--port', help='action container port number', default=8080, type=int)

    subparsers = parser.add_subparsers(title='available commands', dest='cmd')

    initmenu = subparsers.add_parser('init', help='initialize container with src or zip/tgz file')
    initmenu.add_argument('-b', '--binary', help='treat artifact as binary', action='store_true')
    initmenu.add_argument('-r', '--run', nargs='?', default=None, help='run after init')
    initmenu.add_argument('main', nargs='?', default='main', help='name of the "main" entry method for the action')
    initmenu.add_argument('artifact', help='a source file or zip/tgz archive')
    initmenu.add_argument('env', nargs='?', help='the environment variables to export to the action, either a reference to a file or an inline JSON object', default=None)

    runmenu = subparsers.add_parser('run', help='send arguments to container to run action')
    runmenu.add_argument('payload', nargs='?', help='the arguments to send to the action, either a reference to a file or an inline JSON object', default=None)

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

def init(args):
    main = args.main
    artifact = args.artifact

    if artifact and (args.binary or artifact.endswith('.zip') or artifact.endswith('tgz') or artifact.endswith('jar')):
        with open(artifact, 'rb') as fp:
            contents = fp.read()
        contents = str(base64.b64encode(contents), 'utf-8')
        binary = True
    elif artifact is not '':
        with(codecs.open(artifact, 'r', 'utf-8')) as fp:
            contents = fp.read()
        binary = False
    else:
        contents = None
        binary = False

    r = requests.post(
        containerRoute(args, 'init'),
        json = {
            "value": {
                "code": contents,
                "binary": binary,
                "main": main,
                "env": processPayload(args.env)
            }
        })

    print(r.text)

    if r.status_code == 200 and args.run is not None:
        runArgs = objectify({})
        runArgs.__dict__ = args.__dict__.copy()
        runArgs.payload = args.run
        run(runArgs)

def run(args):
    value = processPayload(args.payload)
    if args.verbose:
        print('Sending value: %s...' % json.dumps(value)[0:40])
    r = requests.post(containerRoute(args, 'run'), json = {"value": value})
    print(r.text)

def processPayload(payload):
    if payload and os.path.exists(payload):
        with open(payload) as fp:
            return json.load(fp)
    try:
        d = json.loads(payload if payload else '{}')
        if isinstance(d, dict):
            return d
        else:
            raise
    except:
        print('payload must be a JSON object.')
        sys.exit(-1)

if __name__ == '__main__':
    main()
