#!/usr/bin/env python
#
#  The OpenDiamond Platform for Interactive Search
#
#  Copyright (c) 2009-2012 Carnegie Mellon University
#  All rights reserved.
#
#  This software is distributed under the terms of the Eclipse Public
#  License, Version 1.0 which can be found in the file named LICENSE.
#  ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS SOFTWARE CONSTITUTES
#  RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT
#

from __future__ import print_function
from builtins import str
from datetime import datetime, timedelta
from dateutil.tz import tzutc
from optparse import OptionParser
import os
import sys

from opendiamond.scope import ScopeCookie


def main():
    # Parse command-line options
    default_key = os.path.expanduser(os.path.join('~', '.diamond', 'key.pem'))
    parser = OptionParser(
        usage='%prog [--help] [options] - generate scope cookie',
        description="""\
Generates an OpenDiamond(R) cookie. If no --scopeurl argument is given, the
list of scope URLs will be read from stdin."""
    )
    parser.add_option(
        '-v', '--verbose', dest='verbose', action='store_true',
        help='be verbose')
    parser.add_option(
        '-b', '--blaster', metavar='url', dest='blaster', default=None,
        help='JSON Blaster that can relay for the specified servers')
    parser.add_option(
        '-s', '--server', metavar='host', dest='servers', action='append',
        default=[],
        help='server that accepts the cookie (can be repeated)')
    parser.add_option(
        '-e', '--expire', metavar='time', dest='expiry', default=3600,
        help='time in seconds until cookie expires (3600)')
    parser.add_option(
        '-k', '--key', metavar='path', dest='keyfile', default=default_key,
        help='X509 private key ($HOME/.diamond/key.pem)')
    parser.add_option(
        '-u', '--scopeurl', metavar='host', dest='scopeurls', action='append',
        default=[],
        help='URL from which scopelist can be retrieved (can be repeated)')
    (opts, args) = parser.parse_args()
    if len(args) > 0:
        parser.error('Unrecognized trailing arguments')
    if len(opts.servers) == 0:
        parser.error('Specify one or more servers')
    try:
        expiretime = int(str(opts.expiry), 10)
    except ValueError:
        parser.error('Unable to parse expire time')

    # Read private key
    keydata = open(opts.keyfile, 'rb').read()

    # Calculate cookie expiration time
    expires = datetime.now(tzutc()) + timedelta(seconds=expiretime)

    # Gather scope data
    scopeurls = opts.scopeurls
    if len(scopeurls) == 0:
        scopeurls = [u.strip() for u in sys.stdin]

    # Build and sign the cookie
    cookie = ScopeCookie.generate(opts.servers, scopeurls, expires, keydata,
                                  blaster=opts.blaster)

    # Print decoded cookie to stderr if verbose
    if opts.verbose:
        print(str(cookie), file=sys.stderr)

    # Print final cookie to stdout
    print(cookie.encode(), end=' ')


if __name__ == '__main__':
    try:
        main()
    except Exception as e:
        raise