# -*- coding: utf-8 -*-

"""
This program calls a chain of rest webservices of Agyo to return a valid token

Needs:

 Virtualenv with python 2.7 and requests package installed

Params:

 -u --url   url of the webservice

 -i --id     company id

 -s --secret company secret

 -o --output file name for the output

 --unsafe    disable ssl verification over https

The result of the script is the token
The token is a (very) long string wich will be written to the output or, if specified, to the output file
Other error messages are written to the standard error
"""

import sys
import json
import hashlib
import requests
from requests.exceptions import SSLError
from requests.structures import CaseInsensitiveDict


def errlog(msg):
    print >> sys.stderr, "%s" % (msg,)


def option_parsing():
    from optparse import OptionParser

    usage = "usage: %prog [options] argument"
    parser = OptionParser(usage=usage)
    parser.add_option("-u", "--url", dest="url", action="store", type="string",
                      help="url api to invoke [REQUIRED]")
    parser.add_option("-i", "--id", dest="id", action="store", type="string",
                      help="company id [REQUIRED]")
    parser.add_option("-s", "--secret", dest="secret", action="store", type="string",
                      help="company secret [REQUIRED]")
    parser.add_option("-o", "--output", dest="output", action="store", type="string",
                      help="output file name")
    parser.add_option("--unsafe", action="store_false", dest="safe", default=True,
                      help="disable ssl cert verification")
    opz, args = parser.parse_args()
    if not opz.url:
        parser.error("-u param is required; try -h")
    if not opz.secret or not opz.id:
        parser.error("-i and -s params are required; try -h")
    return opz


def do_authentication(url, userid, secret, safe):
    try:
        headers = CaseInsensitiveDict()
        headers["Accept"] = "application/json"
        headers["Content-Type"] = "application/json"
        headers["X-App-Name"] = "TS160"
        headers["X-App-Version"] = "2021"
        headers["User-Agent"] = "GNU/Linux"
        headers["X-Correlation-ID"] = "1"
        # nonce
        jdata = json.dumps({"id": userid})
        resp = requests.post(url + "/api/v2/nonces", headers=headers, data=jdata, verify=safe)
        rdata = json.loads(resp.content)
        nonce = rdata["nonce"]
        # token
        digest = hashlib.sha256(hashlib.sha256(userid + secret).hexdigest() + nonce).hexdigest()
        jdata = json.dumps({"id": userid, "digest": digest})
        resp = requests.post(url + "/api/v2/tokens", headers=headers, data=jdata, verify=safe)
        rdata = json.loads(resp.content)
        token = rdata["accessToken"]
        print token
        sys.exit(0)
    except SSLError:
        errlog("SSL cert error. Try --unsafe option (at your own risk).")
        sys.exit(2)
    except Exception as e:
        errlog(e.__class__)
        sys.exit(3)


if __name__ == "__main__":
    options = option_parsing()
    # if the output file is requested, the stdout is redirected to it
    if options.output:
        sys.stdout = open(options.output, 'w')
    do_authentication(url=options.url, userid=options.id, secret=options.secret, safe=options.safe)
