# =======================================================================================================================
# getopt code copied since gnu_getopt is not available on jython 2.1
# =======================================================================================================================
class GetoptError(Exception):
    opt = ""
    msg = ""

    def __init__(self, msg, opt=""):
        self.msg = msg
        self.opt = opt
        Exception.__init__(self, msg, opt)

    def __str__(self):
        return self.msg


def gnu_getopt(args, shortopts, longopts=[]):
    """getopt(args, options[, long_options]) -> opts, args

    This function works like getopt(), except that GNU style scanning
    mode is used by default. This means that option and non-option
    arguments may be intermixed. The getopt() function stops
    processing options as soon as a non-option argument is
    encountered.

    If the first character of the option string is `+', or if the
    environment variable POSIXLY_CORRECT is set, then option
    processing stops as soon as a non-option argument is encountered.
    """

    opts = []
    prog_args = []
    if type("") == type(longopts):
        longopts = [longopts]
    else:
        longopts = list(longopts)

    # Allow options after non-option arguments?
    all_options_first = False
    if shortopts.startswith("+"):
        shortopts = shortopts[1:]
        all_options_first = True

    while args:
        if args[0] == "--":
            prog_args += args[1:]
            break

        if args[0][:2] == "--":
            opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
        elif args[0][:1] == "-":
            opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
        else:
            if all_options_first:
                prog_args += args
                break
            else:
                prog_args.append(args[0])
                args = args[1:]

    return opts, prog_args


def do_longs(opts, opt, longopts, args):
    try:
        i = opt.index("=")
    except ValueError:
        optarg = None
    else:
        opt, optarg = opt[:i], opt[i + 1 :]

    has_arg, opt = long_has_args(opt, longopts)
    if has_arg:
        if optarg is None:
            if not args:
                raise GetoptError("option --%s requires argument" % opt, opt)
            optarg, args = args[0], args[1:]
    elif optarg:
        raise GetoptError("option --%s must not have an argument" % opt, opt)
    opts.append(("--" + opt, optarg or ""))
    return opts, args


# Return:
#   has_arg?
#   full option name
def long_has_args(opt, longopts):
    possibilities = [o for o in longopts if o.startswith(opt)]
    if not possibilities:
        raise GetoptError("option --%s not recognized" % opt, opt)
    # Is there an exact match?
    if opt in possibilities:
        return False, opt
    elif opt + "=" in possibilities:
        return True, opt
    # No exact match, so better be unique.
    if len(possibilities) > 1:
        # XXX since possibilities contains all valid continuations, might be
        # nice to work them into the error msg
        raise GetoptError("option --%s not a unique prefix" % opt, opt)
    assert len(possibilities) == 1
    unique_match = possibilities[0]
    has_arg = unique_match.endswith("=")
    if has_arg:
        unique_match = unique_match[:-1]
    return has_arg, unique_match


def do_shorts(opts, optstring, shortopts, args):
    while optstring != "":
        opt, optstring = optstring[0], optstring[1:]
        if short_has_arg(opt, shortopts):
            if optstring == "":
                if not args:
                    raise GetoptError("option -%s requires argument" % opt, opt)
                optstring, args = args[0], args[1:]
            optarg, optstring = optstring, ""
        else:
            optarg = ""
        opts.append(("-" + opt, optarg))
    return opts, args


def short_has_arg(opt, shortopts):
    for i in range(len(shortopts)):
        if opt == shortopts[i] != ":":
            return shortopts.startswith(":", i + 1)
    raise GetoptError("option -%s not recognized" % opt, opt)


# =======================================================================================================================
# End getopt code
# =======================================================================================================================
