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

"""
Utilities for command-line programs.
"""

import sys, json, optparse, os
from collections import Sequence, Mapping
from qpid_dispatch_site import VERSION
from proton import SSLDomain, Url
try:
    from proton.utils import SyncRequestResponse, BlockingConnection
except ImportError:
    from qpid_dispatch_internal.proton_future.utils import SyncRequestResponse, BlockingConnection


class UsageError(Exception):
    """
    Raise this exception to indicate the usage message should be printed.
    Handled by L{main}
    """
    pass

def main(run, argv=sys.argv, op=None):
    """
    Call run(argv) with exception handling, do appropriate sys.exit().
    @param op: an OptionParser to use for usage related error messages.
    @return: exit value for sys.exit
    """
    try:
        run(argv)
        return 0
    except KeyboardInterrupt:
        print
    except UsageError, e:
        op.error(e)
    except Exception, e:
        if "_QPID_DISPATCH_TOOLS_DEBUG_" in os.environ:
            raise
        print "%s: %s" % (type(e).__name__, e)
    return 1

def check_args(args, maxargs=0, minargs=0):
    """
    Check number of arguments, raise UsageError if in correct.
    @param maxargs: max number of allowed args after command or None to skip check.
    @param minargs: min number of allowed args after command or None to skip check.
    @return args padded with None to maxargs.
    """
    if minargs is not None and len(args) < minargs:
        raise UsageError("Not enough arguments, got %s need %s" % (len(args), minargs))
    if maxargs is not None and len(args) > maxargs:
        raise UsageError("Unexpected arguments: %s" % (" ".join(args[maxargs:])))
    return args + [None] * (maxargs - len(args))

def connection_options(options, title="Connection Options"):
    """Return an OptionGroup for connection options."""
    group = optparse.OptionGroup(options, title)
    group.add_option("-b", "--bus", action="store", type="string", default="0.0.0.0",
                     metavar="URL", help="URL of the messaging bus to connect to (default %default)")
    group.add_option("-r", "--router", action="store", type="string", default=None,
                     metavar="ROUTER-ID", help="Router to be queried")
    group.add_option("-t", "--timeout", action="store", type="float", default=5, metavar="SECS",
                      help="Maximum time to wait for connection in seconds (default %default)")
    group.add_option("--ssl-certificate", action="store", type="string", metavar="CERT",
                     help="Client SSL certificate (PEM Format)")
    group.add_option("--ssl-key", action="store", type="string", metavar="KEY",
                     help="Client SSL private key (PEM Format)")
    group.add_option("--ssl-trustfile", action="store", type="string", metavar="TRUSTED-CA-DB",
                     help="Trusted Certificate Authority Database file (PEM Format)")
    group.add_option("--ssl-password", action="store", type="string", metavar="PASSWORD",
                     help="Certificate password, will be prompted if not specifed.")
    return group

def opts_url(opts):
    """Fix up default URL settings based on options"""
    url = Url(opts.bus)

    # If the options indicate SSL, make sure we use the amqps scheme.
    if opts.ssl_certificate or opts.ssl_trustfile:
        url.scheme = "amqps"

    return url

def opts_ssl_domain(opts, mode=SSLDomain.MODE_CLIENT):
    """Return proton.SSLDomain from command line options or None if no SSL options specified.
    @param opts: Parsed optoins including connection_options()
    """
    certificate, key, trustfile, password = opts.ssl_certificate, opts.ssl_key, opts.ssl_trustfile, opts.ssl_password
    if not (certificate or trustfile): return None
    domain = SSLDomain(mode)
    if trustfile:
        domain.set_trusted_ca_db(trustfile)
        domain.set_peer_authentication(SSLDomain.VERIFY_PEER, trustfile)
    if certificate:
        domain.set_credentials(certificate, key, password)
    return domain

class Option(optparse.Option):
    """Addes two new types to optparse.Option: json_map, json_list"""

    def check_json(option, opt, value):
        """Validate a json value, for use with L{Option}"""
        try:
            result = json.loads(value)
            if option.type == 'json_list' and not isinstance(result, Sequence) or \
               option.type == 'json_map' and not isinstance(result, Mapping):
                raise ValueError()
            return result
        except ValueError:
            raise optparse.OptionValueError("%s: invalid %s: %r" % (opt, option.type, value))

    TYPES = optparse.Option.TYPES + ("json_list", "json_map")
    TYPE_CHECKER = dict(optparse.Option.TYPE_CHECKER, json_list=check_json, json_map=check_json)


class OptionParser(optparse.OptionParser):
    """Adds standard --version option to optparse.OptionParser"""
    def __init__(self, *args, **kwargs):
        optparse.OptionParser.__init__(self, *args, **kwargs)
        def version_cb(*args):
            print VERSION
            exit(0)

        self.add_option("--version", help="Print version and exit.",
                        action="callback", callback=version_cb)

