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

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

Needs:

 Virtualenv with python 2.7 and zeep package installed

Params:

 -w --wsdl   url of the webservice wsdl

 -i --id     company id

 -s --secret company secret (-a only)

 -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
"""

from requests import Session
from requests.exceptions import SSLError
from zeep import Client
from zeep.transports import Transport
from zeep.exceptions import Fault
import sys
import hashlib


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("-w", "--wsdl", dest="wsdl", action="store", type="string",
                      help="url 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.wsdl:
        parser.error("-w 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(wsdl, userid, secret, safe):
    try:
        session = Session()
        session.verify = safe
        transport = Transport(session=session)
        client = Client(wsdl, transport=transport)
        nonce = client.service.getNonce(id=userid)
        digest = hashlib.sha256(hashlib.sha256(userid + secret).hexdigest() + nonce).hexdigest()
        token = client.service.verifyDigest(id=userid, digest=digest)
        client.service.verifyToken(id=userid, token=token)
        print token
        sys.exit(0)
    except Fault as e:
        errlog(e.message)
        sys.exit(1)
    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(wsdl=options.wsdl, userid=options.id, secret=options.secret, safe=options.safe)
